晴耕雨読

working in the fields on fine days and reading books on rainy days

PowerShellでファイル内の文字列置換 (sed -i) をする

PowerShellでsedのようにファイル内の文字列置換するには、Get-Content, foreach, Set-Content などを組み合わせて使う必要があります。

sed -i (ファイル内の文字列置換)

sed -i と同じようにファイル内の文字列を置換するときは、以下のように複数のコマンドを組み合わせます。

(Get-Content ファイル名) | foreach { $_ -replace "置換前","置換後" } | Set-Content ファイル名

ファイル内が英数字だけなら問題ないですが、日本語が含まれていると文字化けしたまま保存されてしまうので、ファイルのエンコーディングには注意が必要です。 以下は、UTF-8 でエンコードされた text.txt ファイル内の「http:」を「https:」に置換する例です。

$TARGET = "test.txt"
$ENCODING = "UTF8"
(Get-Content $TARGET -Encoding $ENCODING) | `
  foreach { $_ -replace "http:","https:" } | `
  Set-Content $TARGET -Encoding $ENCODING

補足

Get-Content の処理を丸括弧で囲まないと、別のプロセスが掴んでファイル書き込みができなくなります。 パイプライン処理によって、Get-Content のファイル読み込みが1行1行で遅延評価されているためです。 丸括弧は式の評価順を制御するためのものですが、遅延評価させずにすぐに式を評価するためにも使用できます。 パイプラインの前で使用すると、ファイルの中身を全て読み込んで String 型にしてから次の処理に渡すことができます。 これにより、2つのコマンドが同じファイルを参照できるようになります。

PS> Get-Content $TARGET -Encoding $ENCODING | `
>>   foreach { $_ -replace "http:","https:" } | `
>>   Set-Content $TARGET -Encoding $ENCODING

Set-Content : 別のプロセスで使用されているため、プロセスはファイル 'test.txt' にアクセスできません。

参考文献