powershell の Select-String コマンドを使う際の文字コードの指定がややこしかったので、ここにメモしておく。なお、以下の実機検証は Windows10 上で行った。
まず、前提知識として、powershell の Select-String は、いわゆる grep を行うためのコマンド。例えば、以下のように実行する。
Select-String "日本語" *.txt
上記は、カレントディレクトリ配下にある *.txt ファイルから「日本語」という文字列が入った行を見つけるものである。
ここで以下のファイルをカレントディレクトリに配置し、条件を変えつつ Select-String(grep) してみる。
sjis.txt utf16_bomあり.txt utf16_bomなし.txt utf8_bomあり.txt utf8_bomなし.txt
上記の各ファイルは、ファイル名の文字コードでエンコードされており、中に「日本語 (文字コード名)」の文字列が入っている。
まずは、Encoding オプションを付けないパターン
Select-String "日本語" *.txt
結果は以下となった。
utf16_bomあり.txt:1:日本語 (UTF16) utf8_bomあり.txt:1:日本語 (UTF8) utf8_bomなし.txt:1:日本語 (UTF8)
UTF8のファイルとUTF16(BOMあり)のファイルをgrepすることができた。SJISのファイルは grep できない。Encoding オプションを付けない、つまり、デフォルトだとこうなるようだ。
次に、Encoding に UTF8 を指定
Select-String "日本語" *.txt -Encoding UTF8
結果は以下となった。
utf16_bomあり.txt:1:日本語 (UTF16) utf8_bomあり.txt:1:日本語 (UTF8) utf8_bomなし.txt:1:日本語 (UTF8)
最後に、Encoding に Default (日本語WindowsだとSJISを指すらしい) を指定
Select-String "日本語" *.txt -Encoding Default
結果は以下となった。
sjis.txt:1:日本語 (SJIS) utf16_bomあり.txt:1:日本語 (UTF16) utf8_bomあり.txt:1:日本語 (UTF8)
SJISがgrepできるのは想定通り。ただ、ここでも UTF16(BOMあり)がgrepできる理由がよく分からない。あと、なぜか UTF8でもBOMありの場合は grep できている。ややこしい。。
ここまでの検証結果纏め
sjis | utf8(bomあり) | utf8(bomなし) | utf16(bomあり) | utf16(bomなし) | |
---|---|---|---|---|---|
Encoding なし | × | ○ | ○ | ○ | × |
Encoding UTF8 | × | ○ | ○ | ○ | × |
Encoding Default | ○ | ○ | × | ○ | × |
○:Select-String コマンドで grep できた。
×:Select-String コマンドで grep できなかった。
以下は推測、、というか以下のように考えて、自分を納得させている。。
- Encodingオプションの指定にかかわらず、UTF8 や UTF16の BOM ありのファイルを grep できるのは、BOM があるということで powershell の文字コードの自動判定が働くためか。
- UTF16(BOMなし)のファイルは、上記のどの場合でも grep できなかったが、これはそもそもUTF16のファイルにはBOMがあるべきで、それがないものはpowershellが相手にしていないためか。