我可以用更少的代码获得相同的结果吗? 该代码在sample.bat中搜索字符串AROUND LINE {1-9999}和LINE2 {1-9999},并将{1-9999}替换为代码所在的{line number}。
sample.bat:
AROUND LINE 262
LINE2 1964
旧代码:
gc $env:temp\sample.bat | foreach -Begin {$lc = 1} -Process {
$_ -replace "AROUND LINE \d*", "AROUND LINE $lc";
$lc += 1
} | Out-File -Encoding Ascii $env:temp\results.bat
(gc $env:temp\results.bat) | foreach -Begin {$lc = 1} -Process {
$_ -replace "LINE2 \d*", "LINE2 $lc";
$lc += 1
} | Out-File -Encoding Ascii $env:temp\results.bat
当前代码:
(gc $env:temp\sample.bat) | foreach -Begin {$lc = 1} -Process {
$_ -replace "AROUND LINE \d*", "AROUND LINE $lc";
$lc += 1
} | foreach -Begin {$lc = 1} -Process {
$_ -replace "LINE2 \d*", "LINE2 $lc";
} | Out-File -Encoding Ascii $env:temp\sample.bat
预期结果:
AROUND LINE 1
LINE2 2
实际结果:
AROUND LINE 1
LINE2 2
答案 0 :(得分:1)
您可以使用单个正则表达式来完成这项工作:
gc $env:temp\sample.bat | foreach -Begin {$lc = 1} -Process {
$_ -replace '(?<=AROUND LINE |LINE2 )\d+', $lc++
} | Set-Content -Encoding Ascii $env:temp\results.bat
请注意,我使用的是'...'
(单引号)而不是"..."
(双引号)来包围正则表达式,这样可以更好地排除由于PowerShell执行字符串而引起的潜在混淆首先进行扩展(插值)。
$lc++
返回当前的$lc
值,然后再将其增加1
,从而消除了对$lc += 1
语句的需要。
另外,我将Out-File
替换为Set-Content
,因为它们在保存字符串方面在功能上相同,但是后者更快。
最后,要匹配一个或多个数字,请使用\d+
而不是\d*
。
关于$_ -replace '(?<=AROUND LINE |LINE2 )\d+', $lc++
的注释:
正则表达式(?<=AROUND LINE |LINE2 )\d+
使用后置断言((?<=...)
查找(|
)字符串AROUND LINE
或字符串LINE2
之前的字符串或更多(+
个数字(\d
)。
$lc++
是替换操作数:它返回变量$lc
的当前值,并随后递增其值 ;请注意,即使$lc
是一个数字([int]
),PowerShell也会自动将其转换为字符串以进行替换。
不过,通常,您可以简单地 chain -replace
操作:
# ...
$_ -replace 'AROUND LINE \d+', "AROUND LINE $lc" -replace 'LINE2 \d+', "LINE2 $lc"
++$lc
# ...