構成ファイルをカスタマイズするためのスクリプトを書いています。このファイル内の文字列の複数のインスタンスを置き換えたいので、PowerShellを使用してジョブを実行しようとしました。
単一の置換では正常に機能しますが、複数の置換を実行すると、ファイル全体を再度解析する必要があり、このファイルは非常に大きいため、非常に遅くなります。スクリプトは次のようになります。
$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
1つのオプションは、-replace
操作を連鎖させることです。各行の末尾にある`
は改行をエスケープするため、PowerShellは次の行の式の解析を続行します。
$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
別のオプションは、中間変数を割り当てることです。
$x = $_ -replace 'something1', 'something1aa'
$x = $x -replace 'something2', 'something2bb'
...
$x
George Howarthによる投稿を複数の置換で適切に機能させるには、ブレークを削除し、出力を変数($ line)に割り当ててから変数を出力する必要があります。
$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
PowerShellのバージョン3を使用すると、置換呼び出しを連結できます。
(Get-Content $sourceFile) | ForEach-Object {
$_.replace('something1', 'something1').replace('somethingElse1', 'somethingElse2')
} | Set-Content $destinationFile
1行につき1つの'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
それらを複数持つことができる場合は、break
ステートメントのif
を削除するだけです。
パイプライン化されたワンライナーの3番目のオプションは、-replacesをネストすることです。
PS> ("ABC" -replace "B","C") -replace "C","D"
ADD
そして:
PS> ("ABC" -replace "C","D") -replace "B","C"
ACD
これにより、実行順序が保持され、読みやすく、パイプラインにきちんと収まります。明示的な制御、自己文書化などのために括弧を使用することを好みます。括弧はなくても機能しますが、それをどこまで信頼しますか?
-Replaceは比較演算子であり、オブジェクトを受け入れ、おそらく変更されたオブジェクトを返します。これが、上記のようにスタックまたはネストできる理由です。
見てください:
help about_operators