* 文字列とファイルのテキストを検索 Select-String [#t2ce8b5f]
** 検索の指定方法 [#q0c1b767]
*** ファイルのテキスト検索 [#w8f2ab67]
Select-String -Path "*.txt" -Pattern "hello"
Patternで指定する文字列はデフォルトで正規表現が使える。
*** エイリアス・PathとPatternの省略 [#q24a467e]
sls "hello" *.txt
*** OR検索 [#vcaf22fe]
sls "hello", "world" *.txt
"hello"または"world"がある行にマッチする。
*** NOT検索 [#d6715519]
sls -Path *.txt -NotMatch -Pattern "hello","world"
"hello"も"world"もない行にマッチする。
*** AND検索 [#y7669726]
sls "hello" *.txt | sls "world"
または
Get-Content *.txt | Where-Object { $_ -match "hello" -and $_ -match "world" }
"hello"と"world"がある行にマッチする。
*** -AllMatchesオプション 各行で複数の一致を検索 [#p64ab945]
"hello, hello"と書かれたtest.txtがあるとする。
PS> gc test.txt
hello, hello
AllMachesオプションなしでは、
PS> $ret = sls "hello" test.txt
PS> $ret.Matches
Groups : {hello}
Success : True
Captures : {hello}
Index : 0
Length : 5
Value : hello
1文字目(Index:0)のhelloだけキャプチャーされる。AllMachesオプションありでは
PS> $ret = sls "hello" test.txt -AllMatches
Groups : {hello}
Success : True
Captures : {hello}
Index : 0
Length : 5
Value : hello
Groups : {hello}
Success : True
Captures : {hello}
Index : 6
Length : 5
Value : hello
1文字目に加えて、5文字目(Index:6)のhelloもキャプチャーされる。
** 検索結果の加工 [#naa22ff5]
*** マッチしたファイル名を取得 [#x5c30e35]
sls "hello" *.txt | Select-Object filename | Get-Unique -AsString
- Select-Objectの結果はMatchInfoオブジェクトなので、Get-UniqueにはAsStringオプションを付けて文字列として解釈するようにする。
** ファイルの文字エンコード [#nc8de040]
以下のようにSJIS/UTF16/UTF8(BOMなし)/UTF8(BOMあり)のファイルがあったとする。
sjis.txt
utf16.txt
utf8-bom.txt
utf8-nobom.txt
*** UTF8とUTF16を検索(デフォルト) [#w61227f6]
PS> sls "日本語" *.txt
utf16.txt:1:日本語
utf8-bom.txt:1:日本語
utf8-nobom.txt:1:日本語
- Encodingオプションなしの、デフォルトでは、UTF8(BOMあり、なし共に)とUTF16(UTF16には必ずBOMが必要)がマッチする。
*** SJISを検索 [#ga74187d]
PS> sls "日本語" *.txt -Encoding default
sjis.txt:1:日本語
utf16.txt:1:日本語
utf8-bom.txt:1:日本語
- Encodingオプションにdefaultを指定すると、日本語Windowsの既定であるSJISとUTF8(BOMあり)とUTF16がマッチする。
- エクスプローラーのWindows Searchで検索する場合と同じ動作。
*** BOMありのUTF8とUTF16を検索 [#k53f82f3]
PS> sls "日本語" *.txt -Encoding unicode
utf16.txt:1:日本語
utf8-bom.txt:1:日本語
- Encodingオプションにunicodeを指定すると、UTF8(BOMありのみ)とUTF16がマッチする。
- まり使わないかも?
** Bashのgrepとの違い [#d4ebc37b]
- PowerShellのSelect-StringとBashのgrepは文字列を検索するという機能は似ているが、役割は違う。
- なぜかというと、Bashでは|(パイプ)で渡されるのが文字列なので、その抽出の為にgrepを多用せざるをえない。
- 一方、PSではパイプで渡されるのがオブジェクトなので、Select-Stringのような文字列検索コマンドを使う必要性は低い。
- Select-String(やgrep)は文字列を検索する為のコマンドである事、
- PSでSelect-Stringを使うのは多くの場合、テキストファイルの中身を検索する場合である事を理解しておく。
例えば、Bashでは以下のようなケースでgrepコマンドは頻繁に使われるが、
Bash> ls -R * | grep ".txt"
Bash> ps -aux | grep "/usr/bin/python"
PSでは、
PS> dir -r * | select-string ".txt
PS> ps | select-string "chrome"
のようにSelect-Stringコマンドを普通は使わない。dirからパイプに渡るのはSystem.IO.FileInfoオブジェクトであり、psからパイプに渡るのはSystem.Diagnostics.Processオブジェクトだから。つまり、
PS> dir -r -Path *.txt
PS> ps -Name *chrome*
のように、オブジェクトのプロパティを参照して抽出する。
** 参考 [#tbce4165]
- https://technet.microsoft.com/ja-JP/library/dd315403.aspx