Home > other >  In powershell how to -replace on sls Line Object then sort on Line object?
In powershell how to -replace on sls Line Object then sort on Line object?

Time:05-12

What's a good way to add the filter to the Line object:

$.Line = $.Line -replace "^\s procedure\s*", ""

PS> gci -Recurse -Include *.vhd | 
    sls -Pattern "^\s*procedure" | 
    sls -NotMatch -Pattern "end" |  
    Select-Object line, FileName

Output:

    procedure ucm_init(          sim_pkg_bus_host.vhd
 procedure ucm_reset(            sim_pkg_bus_host.vhd
       procedure ucm_idle(       sim_pkg_bus_host.vhd
    procedure ucm_write(         sim_pkg_bus_host.vhd
    procedure ucm_read(          sim_pkg_bus_host.vhd                                               

What I want to see:

PS> gci -Recurse -Include *.vhd | 
    sls -Pattern "^\s*procedure" | 
    sls -NotMatch -Pattern "end" | 
    %{  $_.Line = $_.Line -replace "^\s procedure\s*", "" } | 
    Select-Object line, FileName | 
    Sort-Object Line

Output:

ucm_init(          sim_pkg_bus_host.vhd
ucm_idle(          sim_pkg_bus_host.vhd
ucm_reset(         sim_pkg_bus_host.vhd
ucm_read(          sim_pkg_bus_host.vhd                                               
ucm_write(         sim_pkg_bus_host.vhd

INPUT: sim_pkg_bus_host.vhd

procedure ucm_init(         
...
end procedure;

 procedure ucm_reset(            
 ...
 end procedure;

       procedure ucm_idle(  
       ...
       end procedure;
    procedure ucm_write(    
    ...
    end procedure;

    procedure ucm_read(     
    ...
    end procedure;

CodePudding user response:

Personally, I would create an object array from the matches like:

$result = Get-ChildItem -Path 'X:\WhereTheFilesAre' -Filter '*.vhd' -File -Recurse | ForEach-Object {
    $content = Get-Content -Path $_.FullName -Raw
    # if you don't want the open bracket in the procedure name, use '(?im)^\s*procedure (\w )'
    $regex  = [regex] '(?im)^\s*procedure (\w \()'
    $match  = $regex.Match($content)
    while ($match.Success) {
        [PsCustomObject]@{Procedure = $match.Groups[1].Value; FileName = $_.Name}
        $match = $match.NextMatch()
    }
} | Sort-Object Procedure

# output on screen
$result

Output:

Procedure  FileName            
---------  --------            
ucm_idle(  sim_pkg_bus_host.vhd
ucm_init(  sim_pkg_bus_host.vhd
ucm_read(  sim_pkg_bus_host.vhd
ucm_reset( sim_pkg_bus_host.vhd
ucm_write( sim_pkg_bus_host.vhd

With that result you can do whatever you need, like writing it to a CSV file or format as lines as in your question:

$len = ($result.Procedure | Measure-Object -Property Length -Maximum).Maximum
$result | ForEach-Object {
    "{0,-$($len   4)}{1}" -f $_.Procedure, $_.FileName
}

Output:

ucm_idle(     sim_pkg_bus_host.vhd
ucm_init(     sim_pkg_bus_host.vhd
ucm_read(     sim_pkg_bus_host.vhd
ucm_reset(    sim_pkg_bus_host.vhd
ucm_write(    sim_pkg_bus_host.vhd

CodePudding user response:

Use a regex capture group ((...)) to extract only the substring that is of interest on each line, which you can then expose via a calculated property with Select-Object that operates on the Microsoft.PowerShell.Commands.MatchInfo instances that Select-String outputs:

Get-ChildItem -Recurse -Include *.vhd |
  Select-String '^\s*procedure (\w \()' | 
  Select-Object @{ n='Line'; e={ $_.Matches.Groups[1].Value } }, FileName | 
  Sort-Object Line

CodePudding user response:

$sls = gci -Recurse -Include *.vhd | sls -Pattern "^\s*procedure" 

for($i=0; $i -lt $sls.Count; $i  ) {
    $sls[$i].Line = $sls[$i].Line -replace "^\s*procedure", ""
    $sls[$i].Line = $sls[$i].Line -replace "\s*\(.*$", ""
}

$sls | 
    Select-Object Line, FileName |
    Sort-Object Line
  • Related