Home > front end >  Reformat these lines in powershell?
Reformat these lines in powershell?

Time:07-13

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...

There is someone to show me how to do that ?

Thanks a lot !

CodePudding user response:

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


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

CodePudding user response:

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