2021年7月11日日曜日

Windows標準コマンド (PowerShell) を使ってsedっぽいことを実現する

コマンドラインを使って文字列操作を行う場合、Linuxではsedコマンドを使って実施するのが鉄板だが、WindowsではPowerShellのコマンドレットを組み合わせることでほぼ同様のことができる。

今回、いくつかsedでよく使う文字列処理のパターンに対して、PowerShellで実行する手順を検証してみたので、その結果を記載する。

文字列処理パターン

今回、以下表の8パターンの文字列処理をPowerShellで実現するコマンドを検証した。

No 文字列処理 コマンド (1行目 : sed、2行目 : PowerShell)
1 置換 sed -e 's/<検索文字列>/<置換文字列>/g' <入力ファイル>
gc <入力ファイル> | % { $_ -creplace "<検索文字列>", "<置換文字列>" }
2 空白行を削除 sed -e '/^$/d' <入力ファイル>
gc <入力ファイル> | ? { $_ -ne "" }
3 コメント(#開始行)を削除 sed -e '/^#/d' <入力ファイル>
gc <入力ファイル> | ? { $_ -notmatch "^#" }
4 改行を削除 tr -d '\n' < <入力ファイル>
gc <入力ファイル> -Raw | % { $_ -replace "`r`n", "" }
5 検索文字列の1行上に追記 sed -e '/<検索文字列>/i <追加文字列>' <入力ファイル>
gc <入力ファイル> -Raw | % { $_ -creplace "<検索文字列>", "<追加文字列>`r`n<検索文字列>" }
6 検索文字列の1行下に追記 sed -e '/<検索文字列>/a <追加文字列>' <入力ファイル>
gc <入力ファイル> -Raw | % { $_ -creplace "<検索文字列>", "<検索文字列>`r`n<追加文字列>" }
7 各行の先頭に文字列を追加 sed -e 's/^/<追加文字列>/g' <入力ファイル>
gc <入力ファイル> | % { "<追加文字列>" + $_ }
8 各行の末尾に文字列を追加 sed -e 's/$/<追加文字列>/g' <入力ファイル>
gc <入力ファイル> | % { $_ + "<追加文字列>" }

テスト用テキストファイル

実行結果を示すために、以下のテキストファイルを使用する。

PS C:\> Get-Content .\test.txt
Test
Test1

Test2

# Test3
Test4

Test5

また、コマンドの記載を簡略化するため、以下の省略法を使用する。

コマンドレット 省略記法
Get-Content gc
ForEach-Object (foreach) %
Where-Object (where) ?
Select-Object select

1. 置換

正規表現を使用しない場合の置換コマンド

置換はいくつか方法があるが、簡単なのは、Get-ContentコマンドレットのReplaceメソッドを使う方法となる。この方法では正規表現は利用できず、大文字・小文字の区別がされる状態で置換される。

PS C:\> (gc .\test.txt).Replace("Test1","Hoge")
Test
Hoge

Test2

# Test3
Test4

Test5

また、置換したテキストをファイルに出力したい場合は、以下の通りOut-Fileコマンドレットを使用する。

PS C:\> (gc .\test.txt).Replace("Test1","Hoge") | Out-File test-out.txt

正規表現を使用する場合の置換コマンド

正規表現使う場合は、以下の通り記載する。大文字・小文字の区別するよう-creplaceを使用しているが、もし大文字・小文字の区別が不要な場合は、-replaceを使用すればよい。

PS C:\> gc .\test.txt | % { $_ -creplace "^Test", "Hoge" }
Hoge
Hoge1

Hoge2

# Test3
Hoge4

Hoge5

2. 空白行を削除

空白行を削除する場合は、Where-Objectコマンドレットで「""」以外の行を出力させることで対応する。

PS C:\> gc .\test.txt | ? { $_ -ne "" }
Test
Test1
Test2
# Test3
Test4
Test5

3. コメント(#から始まる行)を削除

以下の通り実行すれば実現できる。

PS C:\> gc .\test.txt | ? { $_ -notmatch "^#" }
Test
Test1

Test2

Test4

Test5

コメントと空白行を同時に削除する場合は、-andを使って以下のように実行すればよい。

PS C:\> (gc .\test.txt) | ? { $_ -notmatch "^#"  -and $_ -ne "" }
Test
Test1
Test2
Test4
Test5

4. 改行を削除

Get-Content-Rawパラメータを付けると、改行コードなども含めて出力されるので、これを利用すして改行コードを置換して消すことで改行を削除して、すべてのテキストを1行で出力させることができる。

PS C:\> gc .\test.txt -Raw | % { $_ -replace "`r`n", "" }
TestTest1Test2# Test3Test4Test5

5. 検索文字列の1行上に追記

以下を実行する。なお、わかりやすくするため、検索文字列を$strに、追加文字列を$add_strに代入している。

PS C:\> $str="Test2"
PS C:\> $add_str="Test1.5"
PS C:\> gc .\test.txt -Raw | % { $_ -creplace "$str", "$add_str`r`n$str" }
Test
Test1

Test1.5
Test2

# Test3
Test4

Test5

6. 検索文字列の1行下に追記

以下を実行する。なお、わかりやすくするため、検索文字列を$strに、追加文字列を$add_strに代入している。

PS C:\> $str="Test2"
PS C:\> $add_str="Test1.5"
PS C:\> gc .\test.txt -Raw | % { $_ -creplace "$str", "$str`r`n$add_str" }
Test
Test1

Test2
Test1.5

# Test3
Test4

Test5

7. 各行の先頭に文字列を追加

以下を実行する。foreachで各行に対して先頭に文字列を連結する。

PS C:\> gc .\test.txt | % { "Hoge1_" + $_ }
Hoge1_Test
Hoge1_Test1
Hoge1_
Hoge1_Test2
Hoge1_
Hoge1_# Test3
Hoge1_Test4
Hoge1_
Hoge1_Test5

8. 各行の末尾に文字列を追加

以下を実行する。foreachで各行に対して末尾に文字列を連結する。

PS C:\> gc .\test.txt | % { $_ + "_Hoge1" }
Test_Hoge1
Test1_Hoge1
_Hoge1
Test2_Hoge1
_Hoge1
# Test3_Hoge1
Test4_Hoge1
_Hoge1
Test5_Hoge1

更新履歴

  • 2020/6/23 新規作成
  • 2021/7/11 「文字列処理パターン」の表にsedだけでなく、PowerShellのコマンド構文を記載

0 件のコメント:

コメントを投稿

人気の投稿