ja ja en en ja ja ja ja ja ja ja ja ja ja en ja en ja en ja ja ja ja ja ja ja ja ja ja en ja en ja ja ja ja ja ja ja ja ja ja uk kn en en en vi ja ja en ja en ja ja ja ja ja ja ja ja ja ja en ja ja ja pl nl ja de ja ja de ja ja en ja ja de ja ja sv ja ja ja ja ja en ja ja ja ja ja ja ja ja ja ja ja ja ja ja ja jbo en en ja nl nb en ko it en it it it en fr it ja ja en la fi ja it it it pt it de en ja en en it fr it en it nb it ja ja ja ja en ja ja ja ja ja ja ja ja ja
外部アプリケーションなしのWindowsでgrepみたいなことをする - Sanwa Systems Tech Blog
$utf8 = New-Object System.Text.UTF8Encoding($False) #BOMなしUTF-8 $result = Select-String "FATAL|ERROR" *.log -Encoding default # 検索結果を取得 [System.IO.File]::WriteAllLines("result4.txt", ($result | % { $_.get_line() }), $utf8) # 出力
2015-04-21 19:30:00 ERROR カリカリがないです 2015-04-21 20:00:00 DEBUG 寝顔がかわいい 2015-04-21 20:30:00 INFO 猫が起きました 2015-04-21 21:30:00 FATAL 猫がPCの上で粗相をしました
cat20150422.log
2015-04-22 12:00:00 INFO 猫が寝ました 2015-04-22 12:30:00 DEBUG 寝顔がかわいい 2015-04-22 13:30:00 INFO 猫が起きました 2015-04-22 14:00:00 FATAL 猫がお皿をひっくり返しました
今回は本文とちょっとだけ関係のある可愛い猫
1. findコマンドを使う
MS-DOS時代からある由緒正しいコマンドです。ただし、 Shift-JISとUTF-16(BOMあり)のファイルにしか対応していません。
C:\blog>find "FATAL" cat20150422.log ---------- CAT20150422.LOG 2015-04-22 14:00:00 FATAL 猫がお皿をひっくり返しました
複数ファイルも受け付けます。
C:\blog>find "FATAL" *.log ---------- CAT20150421.LOG 2015-04-21 21:30:00 FATAL 猫がPCの上で粗相をしました ---------- CAT20150422.LOG 2015-04-22 14:00:00 FATAL 猫がお皿をひっくり返しました
デイリーでローテーションしているログファイルの場合など、ファイル名は不要なケースもあるでしょう。上記の結果からさらに"FATAL"を検索すれば検索結果だけが絞り込めます。
C:\blog>find "FATAL" *.log | find "FATAL" 2015-04-21 21:30:00 FATAL 猫がPCの上で粗相をしました 2015-04-22 14:00:00 FATAL 猫がお皿をひっくり返しました
100行ぐらい出てくるからクリップボードにコピーしたいな……という場合、コマンドの末尾に| clipを付け加えましょう。上記の結果がそのままクリップボードにコピーされます。
C:\blog>find "FATAL" *.log | find "FATAL" | clip
結果をファイル出力する場合はリダイレクトしてください。
C:\blog>find "FATAL" *.log | find "FATAL" > result.txt
2. findstrコマンドを使う
findコマンドの後継がfindstrコマンドで、こちらは正規表現(のごくごく一部)が使えます。@ITの記事が網羅的なので読むと話が早いです。こちらもShift-JISにしか対応していません。
C:\blog>findstr "FATAL" *.log cat20150421.log:2015-04-21 21:30:00 FATAL 猫がPCの上で粗相をしました cat20150422.log:2015-04-22 14:00:00 FATAL 猫がお皿をひっくり返しました
C:\blog>findstr /R "した\>" *.log cat20150421.log:2015-04-21 20:30:00 INFO 猫が起きました cat20150421.log:2015-04-21 21:30:00 FATAL 猫がPCの上で粗相をしました cat20150422.log:2015-04-22 12:00:00 INFO 猫が寝ました cat20150422.log:2015-04-22 13:30:00 INFO 猫が起きました cat20150422.log:2015-04-22 14:00:00 FATAL 猫がお皿をひっくり返しました
3. PowerShellのSelect-Stringコマンドレットを使う
説明するより見た方が早いでしょう。
PS C:\blog> Select-String "FATAL|ERROR" *.log -Encoding default cat20150421.log:1:2015-04-21 19:30:00 ERROR カリカリがないです cat20150421.log:4:2015-04-21 21:30:00 FATAL 猫がPCの上で粗相をしました cat20150422.log:4:2015-04-22 14:00:00 FATAL 猫がお皿をひっくり返しました
PowerShellの標準の文字エンコーディングはUTF-16(BOMあり)です。UTF-8は自動認識してくれるようですが、失敗する場合は文字コードを-Encodingで明示的に指定してあげる必要があります。
UTF-16(BOMあり)
3.1 簡単にファイル出力する
リダイレクトで出力するのが一番手っ取り早いのですが、文字エンコーディングはUTF-16(BOMあり)になります。
PS C:\blog> Select-String "FATAL|ERROR" *.log -Encoding default > result.txt
変更したい場合はOut-Fileを使いましょう。UTF-8にしてみます。
PS C:\blog> Select-String "FATAL|ERROR" *.log -Encoding default | Out-File -FilePath result.txt -Encoding utf8 -Width 10000
最後の-Widthは1行あたりの最大長を指定するもので、これを超えた場合は強制的に改行が入ります。結果の書式はどちらもこのようになります。順にファイル名、行数、内容です。
cat20150421.log:1:2015-04-21 19:30:00 ERROR カリカリがないです cat20150421.log:4:2015-04-21 21:30:00 FATAL 猫がPCの上で粗相をしました
この方法は簡単ですが、難点がいくつかあります。
書式が選べない(上のようになる)
1行が一定の長さを超える場合は強制的に改行が入る(-Widthで指定可能)
UTF-8で出力しても強制的にBOMが入る
3.2 頑張って綺麗にファイル出力する
Select-StringコマンドレットはMicrosoft.PowerShell.Commands.MatchInfoオブジェクトの配列を返します。画面やファイルにテキスト表示する際はこのMatchInfoクラスのToString()メソッドが暗黙的に呼ばれるのですが、これを自分でテキスト変換すれば上述した難点の1つめは解決します。(ついでに書式を自由に決めることもできます)
さらにOut-Fileコマンドレットに任せず、自前でファイル出力を行うことで難点の2つめ・3つめも解決しましょう。.NETのSystem.IO.FileクラスのWriteAllLinesメソッドを直接呼び出します。
これをまとめると冒頭のコードになります。頑張ればワンライナーになりますが……
$utf8 = New-Object System.Text.UTF8Encoding($False) #BOMなしUTF-8 $result = Select-String "FATAL|ERROR" *.log -Encoding default # 検索結果を取得 [System.IO.File]::WriteAllLines("result.txt", ($result | % { $_.get_line() }), $utf8) # 出力
PowerShellを使ってみよう
今回はテキスト検索をネタにしてみました。他環境と比べると記述量は若干増えるので、取っつきづらい面は確かにあります。しかし上でちょっと触れてもらったように、コマンドレットとコマンドレットの間は.NETのオブジェクトでやり取りされるため、柔軟性や自由度は比較になりません。
さして量が多くなければメモ帳で開いて検索することもできますが、それを繰り返すのは時間の無駄ですし、ミスが紛れ込む危険も生じます。PowerShellの利点はWindowsでありさえすれば利用できることがほぼ間違いなく保証されていることで、今後もWindowsでお仕事をするあなたの頼もしい相棒になるでしょう。
nurenezumi 2015-04-22 18:25
AWS明細データの歩き方
こんにちは、AWS担当のwakです。今年もよろしくお願いいたしま…
S3 + AWS Cognito + Google認証でドメイン制限のついた非公開サイトを作る
こんにちは、AWS担当のwakです。 弊社では全社的にG Suiteを導…
石器時代みたいなWebアプリ開発をしていたエンジニアがReact.jsに導かれて2016年にやってき…
はじめに 社内向けのシンプルなWebアプリケーションを作成する…
grepコマンドとPowerShellのsls (Select-String)の比較
こんにちは、PowerShellが好きなwakです。以前書いたこちらの記…
Entity Framework と Linq を使いこなしたい!
こんにちは、最近忙しい、和朗です。 今回は、現在利用しており…
« GoogleAppsScript 携帯端末承認待を取得… OWASP ZAP でWebアプリの脆弱性の検出 そ… »