简体   繁体   English

在powershell中如何在sls Line Object上替换然后对Line对象进行排序?

[英]In powershell how to -replace on sls Line Object then sort on Line object?

What's a good way to add the filter to the Line object:将过滤器添加到 Line 对象的好方法是什么:

$ .Line = $ .Line -replace "^\s+procedure\s*", "" $ .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输入: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;

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:有了这个结果,您可以做任何您需要的事情,例如将其写入 CSV 文件或格式为您的问题中的行:

$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

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:使用正则表达式捕获组( (...) ) 仅提取每行上感兴趣的子字符串,然后您可以通过在Microsoft.PowerShell.Commands.MatchInfo实例上运行的Select-Object计算属性公开这些子字符串Select-String输出:

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

This yields something like (note that I've deliberately excluded the ( following the procedure name):这会产生类似(请注意,我故意排除了(在过程名称之后):

Line      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

You can put "calculated properties" in the Select-Object .您可以将“计算的属性”放在Select-Object中。

Replace this part in your first version of the code:在您的第一个代码版本中替换此部分:

Select-Object line, FileName

with this:有了这个:

Select-Object @{ Name='Line'; Expression={ $_.Line -replace "^\s+procedure\s*", "" }}, FileName

The hash table tells Select-Object to create a new property called "Line" (but we could have called it anything, "MyLine" for instance) and it provides the expression to calculate Line 's value.哈希表告诉Select-Object创建一个名为“Line”的新属性(但我们可以将其命名为任何名称,例如“MyLine”),它提供了计算Line值的表达式。

$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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM