[英]In powershell how to -replace on sls Line Object then sort on Line object?
将过滤器添加到 Line 对象的好方法是什么:
$ .Line = $ .Line -replace "^\s+procedure\s*", ""
PS> gci -Recurse -Include *.vhd |
sls -Pattern "^\s*procedure" |
sls -NotMatch -Pattern "end" |
Select-Object line, FileName
输出:
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
我想看到的:
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
输出:
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
输入: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;
就个人而言,我会从匹配项中创建一个对象数组,例如:
$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
输出:
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
有了这个结果,您可以做任何您需要的事情,例如将其写入 CSV 文件或格式为您的问题中的行:
$len = ($result.Procedure | Measure-Object -Property Length -Maximum).Maximum
$result | ForEach-Object {
"{0,-$($len + 4)}{1}" -f $_.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
使用正则表达式捕获组( (...)
) 仅提取每行上感兴趣的子字符串,然后您可以通过在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
这会产生类似(请注意,我故意排除了(
在过程名称之后):
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
您可以将“计算的属性”放在Select-Object
中。
在您的第一个代码版本中替换此部分:
Select-Object line, FileName
有了这个:
Select-Object @{ Name='Line'; Expression={ $_.Line -replace "^\s+procedure\s*", "" }}, FileName
哈希表告诉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.