PowerShellでsed相当の処理を行う

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

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

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

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

2.上書き保存する

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

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

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

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

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

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

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

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

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

$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.指定した行を削除する

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

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

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

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では何行かに分けて記述しないとならない所がある。
この辺りは、今後改善されていくのだろうか。