Powershell - 查找 get-content 的输出并使用通配符搜索另一个文件中的所有匹配项

问题描述

我正在尝试获取两个单独文件输出,尽管我被卡在通配符上或在文件 B(名称等级)中包含来自文件 A(名称)的 select-string 搜索

文件A内容是:

adam
george
william
assa
kate
mark

文件B内容是:

12-march-2020,Mark-1
12-march-2020,Mark-2
12-march-2020,Mark-3
12-march-2020,william-4
12-march-2020,william-2
12-march-2020,william-7
12-march-2020,kate-54
12-march-2020,kate-12
12-march-2020,kate-44

而且我需要匹配'-'之后的每个名称,所以我的有序输出应该是这样的,它是两个文件的组合作为输出

mark
Mark-1
Mark-2
Mark-3
william
william-2
william-4
william-7
Kate
kate-12
kate-44
kate-54

到目前为止,我只有以下内容,如果您有任何指示或帮助,我将不胜感激。

import-csv (c:\temp\names.csv) | 
    select-string -simplematch (import-csv c:\temp\names-rank.csv -header "Date","Rankedname" | select Rankedname) | 
    set-content c:\temp\names-and-ranks.csv

我想 select-string 是不够的,我需要编写一个循环。

解决方法

您在示例中提供的数据并没有给您太多的工作,并且所需的输出也不是那么直观,大多数情况下,使用 Powershell,您希望最后将数据组合成更丰富的输出. 但无论如何,有了这里给出的和你想要的,下面的代码就会得到你所需要的,我在代码中为你留下了注释

$pathDir='C:\Users\myUser\Downloads\trash'
$names="$pathDir\names.csv"
$namesRank="$pathDir\names-rank.csv"

$nameImport = Import-Csv -Path $names -Header names
$nameRankImport= Import-Csv -Path $namesRank -Header date,rankName

#create an empty array to collect the result
$list=@()

foreach($name in $nameImport){
    
    #get all the match names
    $match=$nameRankImport.RankName -like "$($name.names)*"

    #add the name from the First list
    $list+=($name.names)

    #if there are any matches,add them too
    if($match){
        $list+=$match
    }
}

#Because its a one column string,Export-CSV will now show us what we want
$list | Set-Content -Path "$pathDir\names-and-ranks.csv" -Force
,

为此,我将使用 Group-ObjectWhere-Object 的组合首先按破折号前的名称对所有“RankedName”项目进行分组,然后过滤这些名称以作为我们得到的名称的一部分从“names.csv”文件中输出您需要的属性。

# read the names from the file as string array
$names = Get-Content -Path 'c:\temp\names.csv'  # just a list of names,so really not a CSV

# import the CSV file and loop through
Import-Csv -Path 'c:\temp\names-rank.csv' -Header "Date","RankedName" | 
    Group-Object { ($_.RankedName -split '-')[0] } |      # group on the name before the dash in the 'RankedName' property
    Where-Object { $_.Name -in $names } |                 # use only the groups that have a name that can be found in the $names array
    ForEach-Object {                                   
        $_.Name                                           # output the group name (which is one of the $names)
        $_.Group.RankedName -join [environment]::NewLine  # output the group's 'RankedName' property joined with a newline
    } |
    Set-Content -Path 'c:\temp\names-and-ranks.csv'

输出:

Mark
Mark-1
Mark-2
Mark-3
william
william-4
william-2
william-7
kate
kate-54
kate-12
kate-44