Reformat these lines in powershell?

Viewed 42

I've this type of data :

Name        : Monday
Description : XXX
Type    : Day 1
XXX          : XXX
XXX         : XXX


Name        : Tuesday
Description : XXX
Type    : Day 2
XXX          : XXX
XXX         : XXX


Name        : Wednesday
Description : XXX
Type    : Day 3
XXX          : XXX
XXX         : XXX

I'm able to keep only the Name and the Type :

$file = "D:\XXX\test.txt"

$data = Get-Content $file

foreach($i in $data){

   $Name = $i | findstr /c:"Name"
   $Type = $i | findstr /c:"Type"

   Write-Output $Name
   Write-Output $Type
}

The output is :

Name        : Monday
Type    : Day 1
Name        : Tuesday
Type    : Day 2
Name        : Wednesday
Type    : Day 3

But I would like this output :

Monday/Day 1
Tuesday/Day 2
Wednesday/Day 3

I know how to do that in bash but I'm totally lost with powershell...

Is there someone who can show me how to do that?

2 Answers

If your data is always separated by 2 new lines like that then simply split the string into multiple sections then parse it using ConvertFrom-StringData

(Get-Content $file -Delimiter "`n`n`n") | ForEach-Object {
    $d = $_ | ConvertFrom-StringData -Delimiter ':'
    Write-Host ($d["Name"] + '/' + $d["Type"])
}

Aliased version:

(gc $file -Del "`n`n`n") |% { $d = $_ | ConvertFrom-StringData -D ':'; $d["Name"] + '/' + $d["Type"] }

Note that this requires PowerShell Core 7.0

If there's only an empty line between sections then just change the delimiter from "`n`n`n" to "`n`n"


Solution for PowerShell older than 7.0:

((gc $file -Del "`n`n`n") -replace ':', '=') |% `
    { $d = ConvertFrom-StringData $_; $d["Name"] + '/' + $d["Type"] }

Alternate method:

(((gc $file -Raw) -replace ':', '=') -split "`n`n`n" ) |% `
    { $d = ConvertFrom-StringData $_; $d["Name"] + '/' + $d["Type"] }

Demo on TIO

You could solve this with a regex, like so:

$regex = [Regex]::new('\bName\b\s*\:\s*(?<Name>.*)[\S\s]*?\bType\b\s*\:\s*(?<Type>.*)')
$fileContents = @'    
    Name        : Monday
    Description : XXX
    Type    : Day 1
    XXX          : XXX
    XXX         : XXX
    
    
    Name        : Tuesday
    Description : XXX
    Type    : Day 2
    XXX          : XXX
    XXX         : XXX
    
    
    Name        : Wednesday
    Description : XXX
    Type    : Day 3
    XXX          : XXX
    XXX         : XXX
'@ 
$regex.Matches($fileContents) | %{"$($_.Groups['Name'].Value)/$($_.Groups['Type'].Value)"}

NB: You'd need to tweak your code a little for this to work with it; as currently $data will be an array of strings, rather than a single string.

Amend $data = Get-Content $file to $data = Get-Content $file -Raw to read the input as a single, multi-line, string.

Related