如何使用PowerShellreplace文件中的多个string
我正在编写一个用于定制configuration文件的脚本。 我想在这个文件中replace多个string的实例,我尝试使用PowerShell来完成这个工作。
它适用于单个replace,但是多次replace非常缓慢,因为每次都需要再次parsing整个文件,而且这个文件非常大。 该脚本如下所示:
$original_file = 'path\filename.abc' $destination_file = 'path\filename.abc.new' (Get-Content $original_file) | Foreach-Object { $_ -replace 'something1', 'something1new' } | Set-Content $destination_file
我想要这样的东西,但我不知道该怎么写:
$original_file = 'path\filename.abc' $destination_file = 'path\filename.abc.new' (Get-Content $original_file) | Foreach-Object { $_ -replace 'something1', 'something1aa' $_ -replace 'something2', 'something2bb' $_ -replace 'something3', 'something3cc' $_ -replace 'something4', 'something4dd' $_ -replace 'something5', 'something5dsf' $_ -replace 'something6', 'something6dfsfds' } | Set-Content $destination_file
一种select是将-replace
操作链接在一起。 在每一行的末尾都会有换行符,导致PowerShell继续parsing下一行的expression式:
$original_file = 'path\filename.abc' $destination_file = 'path\filename.abc.new' (Get-Content $original_file) | Foreach-Object { $_ -replace 'something1', 'something1aa' ` -replace 'something2', 'something2bb' ` -replace 'something3', 'something3cc' ` -replace 'something4', 'something4dd' ` -replace 'something5', 'something5dsf' ` -replace 'something6', 'something6dfsfds' } | Set-Content $destination_file
另一个select是分配一个中间variables:
$x = $_ -replace 'something1', 'something1aa' $x = $x -replace 'something2', 'something2bb' ... $x
为了让George Howarth能够正确地使用多个replace工作,您需要删除中断,将输出分配给一个variables($ line),然后输出variables:
$lookupTable = @{ 'something1' = 'something1aa' 'something2' = 'something2bb' 'something3' = 'something3cc' 'something4' = 'something4dd' 'something5' = 'something5dsf' 'something6' = 'something6dfsfds' } $original_file = 'path\filename.abc' $destination_file = 'path\filename.abc.new' Get-Content -Path $original_file | ForEach-Object { $line = $_ $lookupTable.GetEnumerator() | ForEach-Object { if ($line -match $_.Key) { $line = $line -replace $_.Key, $_.Value } } $line } | Set-Content -Path $destination_file
假设每行只能有一个'something1'
或'something2'
等,可以使用查找表:
$lookupTable = @{ 'something1' = 'something1aa' 'something2' = 'something2bb' 'something3' = 'something3cc' 'something4' = 'something4dd' 'something5' = 'something5dsf' 'something6' = 'something6dfsfds' } $original_file = 'path\filename.abc' $destination_file = 'path\filename.abc.new' Get-Content -Path $original_file | ForEach-Object { $line = $_ $lookupTable.GetEnumerator() | ForEach-Object { if ($line -match $_.Key) { $line -replace $_.Key, $_.Value break } } } | Set-Content -Path $destination_file
如果你可以有多个这样的话,只要删除if
语句中的break
。
第三个选项,对于stream水线单线程是嵌套的替代:
PS> ("ABC" -replace "B","C") -replace "C","D" ADD
和:
PS> ("ABC" -replace "C","D") -replace "B","C" ACD
这保留了执行顺序,易于阅读,并整齐地适合pipe道。 我更喜欢使用括号来进行明确的控制,自我logging等。它没有它们,但你相信多远?
-Replace是一个比较运算符,它接受一个对象并返回一个假定修改的对象。 这就是为什么你可以堆叠或嵌套它们,如上所示。
请参见:
help about_operators
使用PowerShell 3版本,您可以将replace调用链接在一起:
(Get-Content $sourceFile) | ForEach-Object { $_.replace('something1', 'something1').replace('somethingElse1', 'somethingElse2') } | Set-Content $destinationFile