将Unix脚本转换为Windows脚本-在PowerShell中模拟Sed命令

时间:2018-06-23 12:13:11

标签: windows powershell batch-file

我有一个运行良好的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"

有什么建议吗?

1 个答案:

答案 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中实现整个脚本 -您将拥有更强大的脚本语言供您使用,并且避免了那些令人头疼的报价问题来自桥接两个不同的世界。