cagit
cagit

Reputation: 23

Joining every two lines in Powershell output

I'm attempting to combine every two lines of the output of this Powershell command:

(((Invoke-WebRequest -Uri "https://www.timeanddate.com/holidays/us/$(Get-Date -Format yyyy)").Content | sls 'id=holidays') -split '<th class="nw" >' | Out-String -Stream) -replace '<|>',',' | ForEach-Object {$_.Split(',')[10,0];}

As you can see if you run it it outputs holidays and their date for the current year like so:

New Year's Day
Jan 1
World Braille Day
Jan 4
Epiphany
Jan 6
Orthodox Christmas Day
Jan 7
International Programmers' Day
Jan 7

etc.

My goal is for the output to be:

New Year's Day Jan 1
World Braille Day Jan 4
Epiphany Jan 6
Orthodox Christmas Day Jan 7
International Programmers' Day Jan 7

etc.

Any suggestions are welcome (I would like to do this without writing output to a file during the process). Or if there is a more efficient way of doing this I'm open to that as well.

Upvotes: 2

Views: 1770

Answers (3)

B-Art
B-Art

Reputation: 121

A little bit of all above: I wanted to convert output from vssadmin to a csv like format.

<#
    List Providers        - List registered volume shadow copy providers
    List Shadows          - List existing volume shadow copies
    List ShadowStorage    - List volume shadow copy storage associations
    List Volumes          - List volumes eligible for shadow copies
    List Writers          - List subscribed volume shadow copy writers
#>

# $vssadmin =  vssadmin list Providers | select -skip 3
# $vssadmin =  vssadmin list Shadows | select -skip 3
# $vssadmin =  vssadmin list ShadowStorage | select -skip 3
# $vssadmin =  vssadmin list Volumes | select -skip 3
# $vssadmin =  vssadmin list writers | select -skip 3
[regex]$pattern = ": "
$vssadmin = foreach($vssrow in $vssadmin){$pattern.replace($vssrow, "#", 1)}
$csv = $vssadmin | ConvertFrom-Csv -Delimiter "#" -Header 'ColumnName', 'ColumnValues'
$csv.ColumnValues | . { 
  begin {
    $headers = $csv.ColumnName | select $_ -unique
    $delimiter = (Get-Culture).Textinfo.ListSeparator
    $output = ($headers -join $delimiter) + [Environment]::NewLine
    $i = -$headers.Count + 1
  }
  process {
    if(0 -eq $i % $headers.Count) {
      $output += $_ + [Environment]::NewLine
    } else {
        $output += $_ + $delimiter
    }
    $i = $i + 1
  }
}

Write-Output $output

$output | ConvertFrom-Csv -Delimiter (Get-Culture).Textinfo.ListSeparator

Hope this will aid anyone else ;-)

Udated to my latest version using # as a temporary ListSeparator.

Upvotes: 0

The Fool
The Fool

Reputation: 20448

You can do something along those lines. For some reason I have to use modulus 4 here and not 2 because when I split like that it makes every second line empty.

$inputData = @"
New Year's Day
Jan 1
World Braille Day
Jan 4
Epiphany
Jan 6
Orthodox Christmas Day
Jan 7
International Programmers' Day
Jan 7
"@

$splitData = $inputData.Split([Environment]::NewLine)

# use a dot here to make the output availabe after the iteration is completed
$splitData | . { 
  begin {
      $output = "" 
      $i = 0
  }
  process {
    if(0 -eq $i % 4) {
      $output += $_ + [Environment]::NewLine
    }
    $i = $i + 1
  }
}

Write-Output $output
# New Year's Day
# World Braille Day
# Epiphany
# Orthodox Christmas Day
# International Programmers' Day

It's not perfect but it works for the given problem I would suggest tinkering with it and make it little more nice. Haven't used PowerShell in a while.

Upvotes: 0

Mathias R. Jessen
Mathias R. Jessen

Reputation: 174465

Use a simple for loop with a counter that increments by 2 every time:

$splitLines = (((Invoke-WebRequest -Uri "https://www.timeanddate.com/holidays/us/$(Get-Date -Format yyyy)").Content | sls 'id=holidays') -split '<th class="nw" >' | Out-String -Stream) -replace '<|>',',' | ForEach-Object {$_.Split(',')[10,0];}

for($i = 0; $i -lt $splitLines.Count; $i += 2){
  $splitLines[$i,($i+1)] -join ' '
}

Upvotes: 1

Related Questions