Forum Discussion

kjetilj's avatar
kjetilj
Copper Contributor
Jul 16, 2021

Importing CSV, splitting names and joining

Hi,

Very new to PowerShell and scripting so I'm trying to do a lab exercise.

 

I'm trying to take input from a CSV file where the name is formatted as "Surname, Name". When I split this it returns as expected each surname and name on separate lines. Trying to "join" this to be "Name Surname" proves to be a challenge. I only get the first "name surname" repeated over and over again.

 

CSV

Name
Rhodes, Dorthy
Woodward, Chauncey
Horn, Julian  

 Script

$Users = Import-Csv -Path "C:\Users\user\Scripts\Labs\StuffForLabs\UserListB.csv" -Delimiter ";" |
ForEach-Object {
($_.Name -split ', ')
}
ForEach ($user in $users) {
$name = @($Users[1] + " " + $Users[0])
$name
}

Running the first part $users returns

Rhodes
Dorthy
Woodward
Chauncey
Horn
Julian

The second part $name returns the same name multiple times

Dorthy Rhodes

 

Would be very thankful for any help and pointers to what I am doing wrong. Have been banging my head against the wall for very long time now.

 

Kjetil

  • kjetilj 

    Here is a possible solutions

     

    $Users = Import-Csv -Path "C:\Users\user\Scripts\Labs\StuffForLabs\UserListB.csv" -Delimiter ";" |
    ForEach-Object {
    ($_.Name -split ', ')
    }
    for ($i=0; $i -le ($users.count-1); $i=$i+2 ){
    $Users[$i+1] + " " + $Users[$i]
    }

     

     

    this is the output

     

    Dorthy  Rhodes
    Chauncey Woodward
    Julian  Horn

     

  • yuzoyox's avatar
    yuzoyox
    Iron Contributor

    kjetilj 

     

    Hi, you need to set a variable and auto implement, because it is printing the same position

    $name = @($Users[1] + " " + $Users[0])

    a logic like these

    $name = @($Users[i] + " " + $Users[j])

     i=1 and j=0, using i=i+2 and j=j+2. You can use a for to print the next position

    • kjetilj's avatar
      kjetilj
      Copper Contributor
      Thank you!
      I understand what your saying, but need to figure out how to do it 🙂
      • yuzoyox's avatar
        yuzoyox
        Iron Contributor

        kjetilj Hi, like these. Dont forget to flag as a solution if it works. Thank you very much

        $Users = Import-Csv -Path "C:\Users\user\Scripts\Labs\StuffForLabs\UserListB.csv" -Delimiter ";" |
        ForEach-Object {
        ($_.Name -split ', ')
        }
        $i=1
        $j=0
        ForEach ($user in $users) {
        $name = @($Users[i] + " " + $Users[j])
        $i=$i+2
        $j=$j+2
        $name
        }

         

  • psophos's avatar
    psophos
    Brass Contributor

    Another way to approach it:

    $Users = Import-Csv -Path "C:\Users\user\Scripts\Labs\StuffForLabs\UserListB.csv" -Delimiter ";"
    foreach ($user in $Users)
    {
        $name = "{1} {0}" -f ($user -split ', ')
        $name
    } 

    Might be a little easier to understand.

    Though I have complicated it with the way I have used the -f format string.

     

    • gastone's avatar
      gastone
      Brass Contributor

      psophosNice the idea to use -f but your code is wrong, not really, the worng part is  that kjetilj 

      using

      Import-Csv -Path "C:\Users\user\Scripts\Labs\StuffForLabs\UserListB.csv" -Delimiter ";"

      for reading a non csv file and the  non present delimiter ";" is necessary to correct the starting point error.

      This is not a CSV!

      Name
      Rhodes, Dorthy
      Woodward, Chauncey
      Horn, Julian  

       

      psophosThis the correct code

      cls
      "The corrected script, for the non CSV..."
      $Users = Import-Csv -Path "C:\Users\user\Scripts\Labs\StuffForLabs\UserListB.csv" -Delimiter ";"
      foreach ($user in $Users)
      {
          $name = "{1} {0}" -f ($user.name -split ',')
          $name
      } 

       

      A more readable code with some comment

      # 
      # skip the first line, so we have a regular csv
      $reallyAcsv=Get-Content -Path "C:\Users\user\Scripts\Labs\StuffForLabs\UserListB.csv" | Select-Object -Skip 1
      # Add header for readability 
      $USRs=$reallyAcsv | ConvertFrom-Csv -Header 'surname','name'
      # Now is easy to understand...
      $USRs|foreach-object {"$($_.name)  $($_.surname)"}
      # if you want only name...
      $USRs|foreach-object {$_.name)}
      # if you want only surname...
      $USRs|foreach-object {$_.surname)}

      The same code in a single line

      "+ In a single line +"
      Get-Content -Path "C:\Users\user\Scripts\Labs\StuffForLabs\UserListB.csv" | 
          Select-Object -Skip 1 | 
              ConvertFrom-Csv -Header 'surname','name' | 
                  foreach-object {"$($_.name)  $($_.surname)"}

      I hope now is more clear the different solutions
      Bye Gas

    • kjetilj's avatar
      kjetilj
      Copper Contributor

      psophos 

      Nice, thank you! Came across similar examples when I searched for a solutions but at that time it didn't make sense to me. Now it's more clear 🙂

       

      Will play around with all approaches as the CSV grows with more real life information. 

Resources