問題9「ログの抽出」につきまして
hirofumimurai opened this issue · 2 comments
本書で紹介されている「teip」コマンドで、日付を整理してから解きたいと考えていました。
以下のようなワンライナーを試みたのですが、期待通りの結果が得られませんでした。
$cat log_range.log | teip -f 4-5 -- bash -c 'sed "s;[;;" | sed "s;];;" | sed "s;/;;g" | date -f - +"%Y%m%d%H%M%S"'
技術的なアドバスをいただきたいです。
よろしくお願いいたします。
一旦 log_range.log
の日付を整理したい状況と理解しました。
また [29/Dec/2016 23:22:10]
のように日付の個所の角括弧を除いて、その中身を date
に与えたい状況にお見受けします。
こちらについて、2 点気づきましたので、問題の切り分けにご活用ください。
teip の挙動
teip
には -f
オプションではなく、-og
オプションで、正規表現でマッチした範囲だけを選択できるので、こちらの表現にして動作をお試しいただくと良いかも知れません。
teip の挙動として teip -f 4-5
という指定をすると、4列目と5列目がそれぞれ独立してbashコマンドに与えられてしまうため、まとめて日付として扱うことができません。
下記のコマンドで、どのような範囲が選択できるかご確認いただけると思います。teip -f 4-5
と比較をいただけると。
$ cat log_range.log | teip -og '\[.*\]'
︙
なお、[
と ]
は正規表現で使われるので \
でエスケープしています。
bash 内の sed
について
私の手元で確認する限り sed "s;[;;" | sed "s;];;"
の個所も、[
と ]
は正規表現として扱われているので、上記と同様にエスケープが必要に見えます。
上記の点を確認の上、改めてチャレンジいただけると良いと思いました。
もし追加で不明点があればご連絡ください。
アドバイスありがとうございます。理解することができました。
teipコマンドで、ひとつの列(フィールド)として、抽出する必要があるということを理解いたしました。
以下のワンライナーで、解答を得ることができました。
$cat log_range.log | awk '{print "STX"$4,$5"EOT",$0}'| teip -og STX.*EOT -- bash -c 'sed "s;STX\[;;" | sed "s;\/;;g" | sed "s;\]EOT;;" | date -f - +"%Y%m%d%H%M%S"' | awk '$1>=20161224210000 && $1<20161225040000' | awk '{$1="";print $0}'
また、ご指摘のとおり、sedの部分の[と]は、エスケープ必要でした。
書籍の解答や別解より、かなり長くなってしまいますが、数値の大小比較のみへと問題を落とし込めるので、自分の感覚的には理解しやすいです。
teipコマンドは、シェルでデータを扱う際、使用価値が高いので、これからも使わせていただこうと思っています。
今回は、アドバイスいただき、ありがとうございました。