PowerShellのSelect-Stringコマンドレットで文字列検索した際、正しい結果が得られない場合の原因と対処方法について解説します。
正しい結果が得られない原因
文字列検索する対象ファイルの文字コードがShift-JISになっていると、検索した文字列が含まれているにも関わらず、結果に表示されない場合があります。
これは、Select-StringコマンドレットがUTF-8で動作するためです。
では、対象ファイルの文字コードをUTF-8にすればいいのでは?と思う方もいるかと思います。
確かに検索対象ファイルの文字コードをUTF-8にすることで正しく検索出来るようになりますが、ファイルの文字コードを変更することが難しい場合があります。
本記事では、文字コードがShift-JISの場合でも、ファイルの内容は変えずに文字列検索を行う方法を説明していきたいと思います。
対処方法1
ここでは、Get-Contentコマンドレットで検索対象ファイルの文字コードを変えてから、Select-Stringコマンドレットを使用する方法を説明します。
以下のように、Get-Contentコマンドレットを使用し、オプション「-Encoding」を設定します。
それをSelect-Stringコマンドレットに渡すことで、文字コードがShift-JISの場合でも正しく処理されるようになります。
Get-Content -Path "住所.txt" -Encoding Default | Select-String -Pattern "東京都"
こちらの方法は1つ問題があり、-Encodingに指定出来る値に「Shift-JIS(SJIS)」がありません。
そのため「Default」を指定していますが、これは環境によっては別の文字コードとして扱われる可能性があります。
そのような場合は、次項以降の方法を試してみてください。
対処方法2
ここでは、.NETの機能を使用する方法を説明します。
まず、System.IO.FileとSystem.Text.Encodingでファイルを読み込みつつ、Select-Stringコマンドレットに渡しています。
[System.IO.File]::ReadLines("C:\Workspace\住所.txt", [System.Text.Encoding]::GetEncoding("Shift_JIS")) | Select-String -Pattern "東京都"
こちらの方法であれば、対処方法1とは異なり、文字コードにShift-JISを指定出来るので環境に依存しません。
ですが、こちらの方法にも問題があり、検索対象ファイルのパスはフルパスで指定する必要があります。
相対パスで指定すると、以下のようなファイルが見つからないというエラーが出ます。
PS C:\Workspace> [System.IO.File]::ReadLines(".\住所.txt", [System.Text.Encoding]::GetEncoding("Shift_JIS")) | Select-String -Pattern "東京都"
"2" 個の引数を指定して "ReadLines" を呼び出し中に例外が発生しました: "ファイル 'C:\Users\user\住所.txt' が見つかりませんでした。"
発生場所 行:1 文字:1
+ [System.IO.File]::ReadLines(".\住所.txt", [System.Text.Encoding]::GetEn ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : FileNotFoundException
相対パスで指定したい場合は、以下のように記述する必要があります。
[System.IO.File]::ReadLines((Resolve-Path ".\住所.txt").Path, [System.Text.Encoding]::GetEncoding("Shift_JIS")) | Select-String -Pattern "東京都"
対象方法としていくつかご紹介しましたが、シンプルな書き方は見やすい反面、環境に依存したりします。
逆に環境に依存しない方法はコマンドが複雑になってしまいます。
実行する環境に合わせて最適なものをご使用頂ければと思います。
記事は以上となります。


コメント