Perlワンライナー覚書

  • 76
    いいね
  • 0
    コメント
この記事は最終更新日から1年以上が経過しています。

0.はじめに

ちゃんとスクリプトを書くほどではないけど、ちょっとした表示の整形や集計をしたい、という時にPerlワンライナーが使えると非常に便利です。今回はPerlワンライナーの基本的な使い方についての覚書になります。

今回試した環境は下記のとおりです。

環境
OS X 10.9.4
perl 5, version 16

1. perlをワンライナーで使う

perlをワンライナーとして利用するためには-eオプションを使います。その後ろに実行したいperlスクリプトを''で囲って指定します。つまり、

基本構文
perl -e '[perl_script]'

のように使います。ではHello,Worldしてみましょう。

Example1
$ perl -e 'print "Hello,World\n";'
Hello,World

また、-leとすることで\nを省略することができます(強制改行)。

Example2
$ perl -le 'print "Hello,World";'
Hello,World

perlスクリプトの部分は当然perlの文法が使えるので、繰返し文や変数定義が利用できます。

Example3
$ perl -le '$string = "Hello,World";for(1..3){print $string;}'
Hello,World
Hello,World
Hello,World

2. 1行ずつ処理する

インプットを1行ずつ処理するためには-nオプションを利用します。次の例は入力したファイルの3の倍数の行の内容に行番号をつけて出力するスクリプトです。

Example4
##データセット
$ cat hello_test.txt
Hello,World1
Hello,World2
Hello,World3
Hello,World4
Hello,World5
Hello,World6
Hello,World7
Hello,World8
Hello,World9
Hello,World10
##perl one liner
$ cat hello_test.txt | perl -nle '$i++;if($i%3==0){print "$i:$_";}'
3:Hello,World3
6:Hello,World6
9:Hello,World9

apacheのアクセスログ(combinedフォーマット)でユーザーエージェント毎の出現回数をカウントすることも可能です。

Example5
#データセット作成
$ ab -c 10 -n 150 -H "User-Agent: SAKANASAN-USER-TEST" localhost/
〜省略〜
#perl one liner
$ cat /var/log/apache2/access_log | perl -nle '$_=~/".*" (".*")/;$hash{$1}++;END{foreach(keys(%hash)){print "$_:\t $hash{$_}";}}'
#結果
"NEKOSAN-USER-TEST":     100
"SAKANASAN-USER-TEST":   150
"SAKANAKUN-USER-TEST":   100
"INUSAN-USER-TEST":      400

perlワンライナーは-nをつけると一行ずつ処理をするので、集計結果はENDブロックに入れて結果を出力します。

3. AWKモード

perlワンライナーは-aオプションをつけることで、AWKのように使うことができます。ただし、AWKでいうところのフィールド変数は$F[0],$F[1],$F[2],...になります。ここでは具体例として、2.で例示したapacheアクセスログの集計を書きなおしてみます。書きなおすついでにユーザエージェントごとにどれだけ通信量があったのかも集計して3列目に出力します。

Example6
#perl one liner
cat /var/log/apache2/access_log | perl -anle '$count{$F[11]}++;$data{$F[11]}+=$F[9]; END{foreach(keys{%count}){print "$_: $count{$_}: $data{$_}";}}'
#結果
"AB-USER-TEST": 100: 4400
"NEKOSAN-USER-TEST": 100: 4400
"SAKANASAN-USER-TEST": 150: 6600
"SAKANAKUN-USER-TEST": 100: 4400
"INUSAN-USER-TEST": 400: 17600

デフォルトのセパレータはスペースですが、-F[セパレータにしたい文字]で変更することが可能です。たとえばCSVファイルを処理したい場合には下記のとおりにします。

$ perl -F, -anle 'perl_script' somefile.csv

4. まとめ

ログで必要ところだけを出力したい、簡単な集計をしたいなどの要望はperlワンライナーで簡単に実現できます。ぜひお試しください。

参考図書
【改訂新版】 サーバ/インフラエンジニア養成読本

この本でPerlワンライナーの存在を知りました。サーバエンジニア志望の人にはおすすめの本です。

参考URL
http://blog.livedoor.jp/dankogai/archives/51026593.html

小飼弾さんによるPerlワンライナー入門です。とても勉強になりました。