在PowerShell中对齐选择字符串的输出
当我使用在PowerShell中对齐选择字符串的输出,powershell,Powershell,当我使用select string时,我几乎总是希望输出对齐,即文件名、行号和找到的文本都应该对齐到列中。从视觉上看,它不会让人分心,通常更容易发现差异。作为一个简单的例子,我在中间文件中注入了一个额外的空间: PS> Get-ChildItem *.cs | Select-StringAligned -pattern override --- FileWithQuiteALengthyName.cs : 34: protected override void Foo() Shor
select string
时,我几乎总是希望输出对齐,即文件名、行号和找到的文本都应该对齐到列中。从视觉上看,它不会让人分心,通常更容易发现差异。作为一个简单的例子,我在中间文件中注入了一个额外的空间:
PS> Get-ChildItem *.cs | Select-StringAligned -pattern override
---
FileWithQuiteALengthyName.cs : 34: protected override void Foo()
ShortName.cs : 46: protected override void Bar()
MediumNameFileHere.cs :123: protected override void Baz()
---
不幸的是,Select-String
不能做到这一点;事实上,它给了这个--你能在这里找到额外的空间吗
PS> Get-ChildItem *.cs | Select-String -pattern override
---
FileWithQuiteALengthyName.cs:34: protected override void Foo()
ShortName.cs:46: protected override void Bar()
MediumNameFileHere.cs:123: protected override void Baz()
---
有没有办法强制选择String
以对齐其输出列
编辑:
哎呀!我忘记了一个重要的部分:如果可能的话,我还想包括-Context
参数,这样可以在匹配前后获得任意数量的行。这可能:
Get-ChildItem *.cs | select-string -pattern override | ft filename, linenumber , line -AutoSize
或者像这样:
Get-ChildItem *.cs | select-string -pattern override |
% { "{0,-20}{1,15}{2,70}" -f $_.filename, $_.linenumber , $_.line }
字符串格式-f
(“{0,-20}{1,15}{2,70}”)的第一部分中的值必须根据使用对象的匹配长度进行检查:
Get-ChildItem *.cs | select-string -pattern override |
select Filename,LineNumber,Line | Format-Table -AutoSize
如果您决定保留它,它也适合导出到csv
添加能够同时使用上下文的要求会使事情变得相当复杂
function ssalign {
begin {$display = @()}
process {
$_ -split "`n" |
foreach {
$display +=
$_ | New-PSObjectFromMatches -Pattern '^(.+)?:([\d]+):(.+)' -Property $null,File,Line,Text
}
}
end {
$display |
foreach {$_.line = ':{0,5}:' -f $_.line}
$display | ft -AutoSize -HideTableHeaders
}
}
Get-ChildItem *.cs | Select-StringAligned -pattern override | ssalign
在此处获取新的PSObject FromMatches函数:
我给@mjolinor打勾,因为他提供了一段很好的代码,并为此付出了努力。尽管如此,一些读者可能会对这种变化感兴趣,特别是我为格式灵活性提供的NameWidth和NumberWidth参数:
filter Select-StringAligned
{
[CmdletBinding()]
Param (
[Parameter(Mandatory=$true,Position=0, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true)]
[string[]]$InputObject,
[Parameter(Mandatory=$true,Position=1)]
[string]$Pattern,
[int[]]$Context = @(0),
[int]$NameWidth = 35,
[int]$NumberWidth = 4)
select-string -Path $InputObject -Pattern $pattern -Context $Context |
% {
$entry = $_
if ($Context[0] -eq 0) { $offset = 0 }
else { $offset = @($entry.Context.PreContext).Count }
$linenum = $entry.LineNumber - $offset - 1
# For some reason need to special case the $list construction; otherwise acts like Context=(1,1)
if ($Context[0] + $Context[1] -eq 0) {
$list = $entry.Line
}
else {
$list = @($entry.Context.PreContext)
$list += $entry.Line
$list += $entry.Context.PostContext
}
$list | % {
if ($entry.FileName.length -lt $nameWidth) { $truncatedName = $entry.FileName }
else { $truncatedName=$entry.FileName.SubString(0,$NameWidth) }
"{0,-$NameWidth}:{1,$NumberWidth}: {2}" -f $truncatedName, $linenum++, $_
}
}
}
下面是一个示例用法。-NameWidth参数允许字段宽度小于(截断)或大于(填充)文件名
$pattern = "public"
Get-ChildItem *.cs |
Select-StringAligned -pattern $pattern -Context 0,2 -NameWidth 20 -NumberWidth 3
在你发布你的答案后,对我提出的附加要求(我的坏:-())有什么想法吗?都德,是的。谢谢