Windows 的本机等效项(或)grep -A
中不存在或多或少直接等效的。但是,在 PowerShell 中带有此参数。findstr
find
grep
Select-String
-Context
如果我正确理解了您的脚本,则意味着:
- 写一个空行
- 写入所有包含“Device_name”的行,然后是四行上下文,然后是一个空行
- 写入所有包含“Device_Oops”的行,然后是 45 行上下文,然后是空行
- 如果包含“Radar”的所有行也包含“Processes:”或在包含“Processes:”的行之后的前 150 行内,则写入所有行
- 写出所有包含三对数字的行,用冒号分隔,还包含“error”或“restart”,不区分大小写。
所以它或多或少归结为:
$f = Get-Content $args[0]
function Emulate-Grep {
begin { $first = $true }
process {
if (!$first) { '--' }
$_.Line
$_.Context.PostContext
$first = false
}
}
Write-Host
$f | Select-String -CaseSensitive -Context 0,4 'Device_name' | Emulate-Grep; Write-Host
$f | Select-String -CaseSensitive -Context 0,45 'Device_Oops' | Emulate-Grep; Write-Host
[string[]]($f | Select-String -CaseSensitive -Context 0,150 'Processes:' | Emulate-Grep) -split "`n" -cmatch 'Radar'; Write-Host
$f -match '\d{2}(:\d{2}){2}' -match 'error|restart'
(未经测试)
请注意,由于试图模拟grep
的输出行为,这有点难看。
如果您只需要匹配行和以下内容,那么我只需编写一个小函数:
function Get-Matching([array]$InputObject, [string]$Pattern, [int]$Context = 0) {
$n = $InputObject.Length - 1
0..$n |
where { $InputObject[$_] -cmatch $Pattern } |
foreach { $InputObject[$_..($_+$Context)] }
}
然后在不再那么复杂的脚本中使用它(仍在尝试重新创建一些输出选择,例如空行):
$f = gc $args[0]
Write-Host
Get-Matching $f Device_name 4; Write-Host
Get-Matching $f Device_Oops 45; Write-Host
Get-Matching $f 'Processes:' 150 | ? { $_ -cmatch 'Radar' }; Write-Host
Get-Matching $f '\d{2}(:\d{2}){2}' | ? { $_ -match 'error|restart' }
您还会注意到我摆脱Select-String
了 cmdlet,这是一个我从未真正理解其用途的 cmdlet(除了提供grep
/的紧密匹配findstr
,但通常我发现其他方式更灵活)。