0

I'm trying to get the output of two separate files although I'm stuck on the wild card or contains select-string search from file A (Names) in file B (name-rank).

The contents of file A is:

adam
george
william
assa
kate
mark

The contents of file B is:

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

And I need to match on every occurrence of the names after the '-' so my ordered output should look like this which is a combination of both files as the output:

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

So far I only have the following and I'd be grateful for any pointers or assistance please.

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

I imagine the select-string isn't going to be enough and I need to write a loop instead.

zett42
  • 25,437
  • 3
  • 35
  • 72
kkp0897
  • 19
  • 1
  • 1
  • The file A example doesn't look like a CSV file.. just plain text with each value on its own line. – Theo Feb 27 '21 at 20:29

2 Answers2

0

The data you give in the example does not give you much to work with, and the desired output is not that intuitive, most of the time with Powershell you would like to combine the data in to a much richer output at the end. But anyway, with what is given here and what you want, the code bellow will get what you need, I have left comments in the code for you

$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
Vasil Nikolov
  • 667
  • 6
  • 16
0

For this I would use a combination of Group-Object and Where-Object to first group all "RankedName" items by the name before the dash, then filter on those names to be part of the names we got from the 'names.csv' file and output the properties you need.

# 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'

Output:

Mark
Mark-1
Mark-2
Mark-3
william
william-4
william-2
william-7
kate
kate-54
kate-12
kate-44
Theo
  • 57,719
  • 8
  • 24
  • 41