基本的な書き方をいくつかメモってくか。
たとえば、コマンドの出力を1行ずつ処理したいとき。
for
じゃできんよ。
for line in `grep hoge access_log`; do 〜〜 done
これじゃ1単語ずつのループになっちまう。行入力でループを形成するときは
read
だ。
grep hoge access_log | while read line 〜〜 done
コマンドの出力に \ とかが含まれるときは、read -r line
とかのほうがええかな。ただしパイプで繋いだときは変数line
のスコープが変わるので注意。
つぎ、こっちが本題。たとえば1行の中から、二つ(以上)の部分を 拾ってそれぞれ別々に後処理したいとき、たとえば、処理したい行の内容が
hoge fuga s d ds d ew a dsads sa jojo
というときに、hoge fuga jojo (もちろん hoge fuga jojo が来るとは分か らない)を全てあとで利用したい(ふつーこういうのはRubyとかPerlでやるんだが、 シェルスクリプトでやることに意義があるんだな)。基本に忠実にやると、
grep hoge somefile | while read -r line; do x=`echo "$line" | awk '{print $1}'` y=`echo "$line" | awk '{print $2}'` z=`echo "$line" | awk '{print $NF}'` done
ってとこか。でもawkを3回も呼んでる。くやしい。てことで、1回で済ませる。
grep hoge somefile | while read -r line; do eval `echo "$line" | \ awk '{printf "x=\"%s\" y=\"%s\" z=\"%s\"", $1, $2, $NF}'` # これで $x, $y, $z が使える。 done
まったくもって自己満足的技法。ひゃーひゃーひゃー。