ITよろづや

ITから生活の参考になる情報を備忘録代わりに残していきます

PowerShell ファイル内の複数の文字列を置き換える方法、コマンド

システムの構築以外にも運用などでPowerShellはよく使うので、ある程度使えるようになっていたほうがいいですね。

 

エクセルとPowerShellは普段の仕事でよく使います。エクセルの関数が使えないものや、処理に時間がかかる場合は、PowerShellを使います。

 

今回も、PowerShellを使って、ファイル内の複数の文字列を置き換える方法、コマンドに関する情報になります。

 

こちらちょっと大量の変換が必要になって探していたのですが、よくある方法で最初に試したらコマンドごとにファイルが複製されて大変なことになって、調べていたら使える情報があったので共有します。

 

それがこちらです。

How to replace multiple strings in a file using PowerShell - Stack Overflow

 

質問内容の抜粋です。

 

===

構成ファイルをカスタマイズするためのスクリプトを書いています。このファイル内の文字列の複数のインスタンスを置き換えたいので、PowerShellを使用して作業を試みました。

1回の置換では問題なく動作しますが、ファイル全体を再度解析する必要があり、このファイルが非常に大きいため、複数回の置換の実行は非常に遅くなります。スクリプトは次のようになります。

 

$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

 

===

 

 

回答一つめ。

 

===

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

 

===

 

参考になったのがこちらです。

 

一つの方法として、-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

 

各行の末尾にある ` は改行をエスケープしというところが、私の状況には合いました。参考までに。

 

Windows PowerShell実践システム管理ガイド 第3版 マイクロソフト関連書