我有一个运行良好的Unix脚本(准确地说是正确的),我需要将其转换为Windows批处理脚本。到目前为止,我已经尝试在代码中插入Powershell命令行,但是它不起作用。请帮忙,我对UNIX脚本和Windows脚本都是陌生的,所以任何帮助都可以。
这是我需要转换的代码行:
#create new file to parse ; exclude past instances of timestamp
parsefile=/tmp/$$.parse
sed -e "1,/$TIMESTAMP/d" -e "/$TIMESTAMP/d" $DSTLOGFILE > $parsefile
到目前为止,我已经尝试在脚本中调用powershell命令行,但是它没有用:
:set_parse_file
@powershell -Command "Get-Content $SCHLOGFILE | Foreach-Object {$_ -replace('1,/"$TIMESTAMP"/d' '/"$TIMESTAMP"/d'} | Set-Content $PARSEFILE"
有什么建议吗?
答案 0 :(得分:1)
PowerShell具有类似 no sed
的构造,用于处理线的 ranges (例如sed
解释{ {1}}是指从第1行到匹配 regex 1,/foo/
)的后一行的连续行的范围
使用逐行处理来模拟此功能会更加冗长,但是如果将输入文件作为一个整体进行处理,则比较简洁的版本是可能的< / em> -这是一个选项,只有文件足够小以适合整个内存使用(PSv5 +语法)。
这是纯PowerShell代码:
foo
请注意,$escapedTimeStamp = [regex]::Escape($TIMESTAMP)
(Get-Content -Raw $SCHLOGFILE) -replace ('(?ms)\A.*?\r?\n.*?' + $escapedTimeStamp + '.*?\r?\n') `
-replace ('(?m)^.*?' + $escapedTimeStamp + '.*\r?\n') |
Set-Content -NoNewline $PARSEFILE
用于确保[regex]::Escape()
的值被视为 literal ,即使该值恰好包含正则表达式元字符(特殊字符)也是如此。表示正则表达式引擎)。
您的$TIMESTAMP
代码不会执行此操作(并且在ksh
中这样做并非易事),因此,如果-相反-ksh
应被解释为正则表达式,只需省略该步骤并直接使用$TIMESTAMP
。
$TIMESTAMP
运算符基于正则表达式,并使用.NET正则表达式引擎。
使用-replace
的{{1}}开关需要PSv3 +,使用Get-Content
的{{1}}开关需要PSv5 +。您可以使此命令在早期版本中工作,但需要更多的精力。
从-Raw
(批处理文件)中调用上述文件变得很麻烦-并且您始终必须谨慎地引用问题-但它应该可以工作:
Set-Content
请注意如何将-NoNewline
参数作为单个cmd.exe
字符串传递,这最终是将代码传递到PowerShell的最安全,概念上最简洁的方法。
另请注意,需要在命令中将 batch 变量作为@powershell.exe -noprofile -command "$escapedTimeStamp = [regex]::Escape('%TIMESTAMP%'); (Get-Content -Raw '%SCHLOGFILE%') -replace ('(?ms)\A.*?\r?\n.*?' + $escapedTimeStamp + '.*?\r?\n') -replace ('(?m)^.*?' + $escapedTimeStamp + '.*\r?\n') | Set-Content -NoNewline '%PARSEFILE%'"
嵌入,并且由于它们包含在上面的嵌入-command
中,因此假设它们的值不包含{{1 }}字符。
因此,考虑在Powershell中实现整个脚本 -您将拥有更强大的脚本语言供您使用,并且避免了那些令人头疼的报价问题来自桥接两个不同的世界。