【Perl】 awk的に使えるワンライナー
投稿日: / 更新日:
この記事は2年以上前に書かれたものです。情報が古い可能性があります。
標準入力やファイルを1行ずつ読み込んで処理するPerlのワンライナーとして、以下のようなものが良く知られています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
[atomitech@node01 ~]$ perl -nle 'print "hello, $1!!" if /^name:\s*(.+)$/' name: John hello, John!! name: Doe hello, Doe!! end ^D [atomitech@node01 ~]$ [atomitech@node01 ~]$ perl -ple 's/^name:\s*(.+)$/hello, $1!!/' name: John hello, John!! name: Doe hello, Doe!! end end ^D [atomitech@node01 ~]$ |
後者には暗黙的なprint
が付加される、という点が異なります。
これらを憶えておくだけで、grep
やsed
的な使い方ができ、しかもPerlの正規表現で複雑なパターンも記述できるので、ちょっとしたテキストの加工などに非常に重宝します。
一方、awk
的な使い方をしたい時、今までは、
1 2 3 4 5 6 7 8 |
[atomitech@node01 ~]$ perl -ple 's/^.+?,.+?,(.+)?,.+?$/$1/' host,domain,ip,descr ip host1,example.com,192.168.11.11,host1 192.168.11.11 host2,example.net,192.168.11.12,host2 192.168.11.12 [atomitech@node01 ~]$ |
のようにやっていたんですが、以下のように-a (auto split)
オプションと-F (Field separator)
オプションを使うことで、もう少し簡単に記述できることを最近知りました。
1 2 3 4 5 6 7 8 |
[atomitech@node01 ~]$ perl -nlaF, -e 'print $F[2]' host,domain,ip,descr ip host1,example.com,192.168.11.11,host1 192.168.11.11 host2,example.net,192.168.11.12,host2 192.168.11.12 [atomitech@node01 ~]$ |
-a
を指定することで、フィールドセパレータでsplit
された文字列が配列@F
へ自動的に格納されるので、上記のように$F[n]
で参照することができます。awk
と違って、フィールド番号は0
から始まりますが、プログラマーから見れば特に不自然はなく、大した問題にはならないでしょう。
なお、いずれのオプションも、詳細はperldoc perlrun
で確認することができます。たまに読み返してみると、新たな発見があるかもしれません。
2012/02/05 00:48 追記: -p
オプションを使えば、もう少し簡単に記述できますね…
1 2 3 4 5 6 7 8 |
[atomitech@node01 ~]$ perl -plaF, -e '$_=$F[2]' host,domain,ip,descr ip host1,example.com,192.168.11.11,host1 192.168.11.11 host2,example.net,192.168.11.12,host2 192.168.11.12 [atomitech@node01 ~]$ |