Search code examples
powershellforeachformattingforeach-object

Formatting ForEach-Object Output in PS Script


I'm trying to output data (a list of songs and albums by RUSH) from a CSV file in my PowerShell script, and I got the data sorted the way I need it, but I can't figure out how to format it the way I need. The following is how my code is currently written:

    $output = Import-CSV $DatabasePath -Delimiter "`t" | Sort-Object @{Expression= 'Year'; Descending = $true}, @{Expression='Song'; Ascending=$true}
    #$output
    $output | ForEach-Object {
        Write-Host "$_.Album "($_.Year)" "`n""
        Write-Host "$tab $_.Song"

and this is how it outputs:


         @{Song=The Story so Far; Album=R40 Live; Year=2015; Notes=Drum solo; interlude during Cygnus X-1}.Song
@{Song=Drumbastica; Album=Clockwork Angels Tour; Year=2013; Notes=Drum solo; interlude during Headlong Flight}.Album  2013   

         @{Song=Drumbastica; Album=Clockwork Angels Tour; Year=2013; Notes=Drum solo; interlude during Headlong Flight}.Song 
@{Song=Here It Is!; Album=Clockwork Angels Tour; Year=2013; Notes=Drum solo}.Album  2013

         @{Song=Here It Is!; Album=Clockwork Angels Tour; Year=2013; Notes=Drum solo}.Song
@{Song=Peke's Repose; Album=Clockwork Angels Tour; Year=2013; Notes=Guitar solo; lead-in to Halo Effect}.Album  2013

I need the output to display like this:

R40 Live (2015)
    The Story so Far
Clockwork Angels Tour (2013)
    Drumbastica
    Here It Is!
    Peke's Repose
    The Percussor
Clockwork Angels (2012)
    BU2B
...

(NOTE: please ignore the color in the example above.) What I'm trying to do after getting the data from the CSV file with the loop is to display the Album name with the Year in paratheses on the first line, then all the songs pertaining to that album tabbed in and in alphabetical order on the lines following the album name. How can I do this?

Edit: Following @BrettFord1999 Suggestions, I got the output to display like this:

R40 Live (2015)  
         The Story so Far
Clockwork Angels Tour (2013)
         Drumbastica
Clockwork Angels Tour (2013)
         Here It Is!
Clockwork Angels Tour (2013)
         Peke's Repose
Clockwork Angels Tour (2013)
         The Percussor
Clockwork Angels (2012)
         BU2B

However, I only want to display the Album once and not multiple times. Is there a way to display each album name once instead of with every song it's linked to?

I would provide the original file except I can't figure out how to share it on here. I'm still new to StackOverflow.


Solution

  • It got a little more complicated than I anticipated because I had to also setup the function to output the formatted song list to file if the user input a file path, but the code now outputs the song list as displayed above. Here is the completed code:

    $prop1 =@{Expression= 'Year'; Descending = $true}
    $prop2 =@{Expression='Album'; Ascending=$true}
    $prop3 =@{Expression='Song'; Ascending=$true}
    
    $tab = [char]9
    $output = Import-CSV $DatabasePath -Delimiter "`t" | Sort-Object $prop1, $prop2, $prop3
    
        $test = @()
        $count = 0
        $output | ForEach-Object {
            $album = $_.Album
            $year = $_.Year
            $song = $_.Song
            if ($output[$count].album -like $output[$count -1].album){
               $test += "$tab$Song"
            } else{
                $test += "$Album ($Year)"
                $test += "$tab$Song"
            } $count++
    
        }  
        if ($path.Length -gt 0){
            $test | Out-File -Path $Path
        } else {
           $test | ForEach-Object {
               Write-Host $_
           }
        }