PowerShellでsed相当の処理を行う

LinuxやUNIXには、ファイルや変数、文字列の置換を行えるsedというコマンドが用意されている。
それと同じことをPowerShellで行う場合、どうすればよいのだろうか。

1.特定の文字列を置換する

基本の使い方である、特定の文字列をただ置き換える場合は「-replace」を利用すればいい。

shell
Get-Content .\test.txt | % { $_ -replace "置換する文字列","置換後の文字列" }

2.上書き保存する

sedの「-i」オプション相当の処理を行わせるには、ただパイプで「Set-Content」「Out-File」を行えば良い、というわけではない。
「Set-Content」ではプロセスが掴んでいるとエラーが出るし、「Out-File」ではただのからファイルが出来上がる。
sedの上書き保存を実現するには、一度置換後のファイルの中身を変数に出力させ、それをファイルに書き込みをさせるという2段階の作業が必要になる。

shell
$data=Get-Content .\test.txt | % { $_ -replace "置換する文字列","置換後の文字列" } $data | Out-File .\test.txt -Encoding UTF8

3.指定した行だけ置換する

sedには、指定した行だけを置換する事ができるが、同じことをPowerShellで行うには以下のようにする。

shell
$data= Get-Content .\test.txt $data[指定したい行番号-1]=$data[指定したい行番号-1] -replace "置換する文字列","置換後の文字列" $data | Out-file .\test.txt -Encoding UTF8

4.指定した行の後に挿入する

指定した行の一行後に挿入を行う場合は、以下のようにする。

shell
$data= Get-Content .\test.txt $data[指定したい行番号-1]=$data[指定したい行番号-1]+"`n挿入したい文字列" $data | Out-File .\test.txt -Encoding UTF8

特定の文字列にマッチした行の一行後に挿入を行う場合は、以下のようにする。

shell
$file = ".\test.txt" $data = Get-Content $file $lnum = $(Select-String -pattern "検索したい文字列" –path $file | foreach { $_.ToString().split(":")[2] } )-1 If ($lnum -ne -1){ $data[$lnum]=$data[$lnum]+"`n挿入したい文字列" $data | Out-File $file -Encoding UTF8 }

5.指定した行を削除する

指定した行を削除する場合、以下のようにする。

shell
$data=Get-Content .\test.txt $data[指定したい行番号-1]=$null $data | Out-File .\test.txt -Encoding UTF8

また、検索した文字列に該当する行を削除する場合、以下のようにする。

shell
file = ".\test.txt" $data = Get-Content $file $lnum = $(Select-String -pattern "検索したい文字列" –path $file | foreach { $_.ToString().split(":")[2] } )-1 If ($lnum -ne -1){ $data[$lnum]=$null $data | Out-File $file -Encoding UTF8 }

うーん…
LinuxやUNIXでsedを使えば一行で終わる内容でも、Powershellでは何行かに分けて記述しないとならない所がある。
この辺りは、今後改善されていくのだろうか。