我有以下Unix shell脚本。我想将其转换为Windows .bat
文件(我知道我可以使用Cygwin而不是将其适应Windows环境。但Cygwin不适合我)。
我知道我可以在线使用Windows PowerShell阅读材料。但我不想花费数小时在线学习基础知识这一次要求。请不要因为懒惰而抨击我。我相信这也有助于其他人成为将来在线搜索的人的快速指南。
这是脚本:
#!/bin/bash
echo ""
cat $1 | grep -A4 "Device_name"; echo ""
cat $1 | grep -A45 "Device_Oops"; echo ""
cat $1 | grep -A150 "Processes:" | sed '/Radar/q'; echo ""
cat $1 | grep -E '[0-9][0-9]:[0-9][0-9]:[0-9][0-9]' | grep -i -E 'error|restart'
要回答有关我尝试的问题,我无法运行“find
”命令,该命令相当于grep
每个网站http://tldp.org/LDP/abs/html/dosbatch.html
这是我的Joy.txt
文件(接下来的两行):
Device_name router@home
testing only
然后在PowerShell提示符下运行以下命令:
cat Joy.txt | find "Device_name"
我原本希望看到上面文件中的第一行。但相反,我得到的参数格式不正确错误。有人可以帮忙吗?
答案 0 :(得分:4)
grep -A
(或findstr
),Windows'中不存在或多或少直接等效的find
。原生grep
等价物。但是,PowerShell中的Select-String
具有-Context
参数。
如果我正确理解您的脚本,则意味着:
所以它或多或少归结为:
$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(除了提供grep
/ findstr
的近似匹配,但是通常我发现其他方法更灵活。)
答案 1 :(得分:0)