技術メモ

神奈川在住のITエンジニアの備忘録。おもにプログラミングやネットワーク技術について、学んだことを自分の中で整理するためにゆるゆると書いています。ちゃんと検証できていない部分もあるのでご参考程度となりますが、誰かのお役に立てれば幸いです。

powershell の Select-String を使う際の文字コード

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)

UTF8がgrepできるのは想定通りだが、UTF16(BOMあり)がgrepできる理由がよく分からない。。

最後に、Encoding に Default (日本語WindowsだとSJISを指すらしい) を指定
Select-String "日本語" *.txt -Encoding Default

結果は以下となった。

sjis.txt:1:日本語 (SJIS)
utf16_bomあり.txt:1:日本語 (UTF16)
utf8_bomあり.txt:1:日本語 (UTF8)

SJISgrepできるのは想定通り。ただ、ここでも 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が相手にしていないためか。