« DBIx::CSVDumperっての作った | メイン | そういえばYAPCのチケットうってるらしいですよ »

2012年7月28日

awkの代わりにperlを使おう

perlのコマンドラインオプションには-aってのがあります。これはawkモードです。perl --help見るとautosplit modeとか書いてありますが。

perlは-pや-nオプションを渡す事によってファイルを一行づつ処理してくれますが、その時に-aオプションを渡すと@F配列にフィールドの情報を自動的に入れてくれます。

フィールドのセパレータはデフォルトではスペースですが、-Fオプションで指定可能です。

カンマ区切りのテキストの、最初のフィールドだけを表示したい場合は以下の様な感じ。

% cat test.txt
server1,1343363124,30,/video.php
server2,1343363110,20,/profile.php
server3,1343363115,7,/login.php
server1,1343363105,8,/profile.php
% perl -aF, -nE 'say$F[0]' test.txt
server1
server2
server3
server1

awkでは$1,$2..にフィールドが入りますが、perlでは$F[0],$F[1]...に入ります。

行毎の処理をperlの文法で書けるので、僕はawk使わないでperl使うことにしています。僕がシェル力が足りないのもあって、なるべくperlでやりたい派。

てことで以下の問にも答えてみます。現実的に自分がやりそうな方法と、無理やりperlワンライナーやった方法を載せます。自分がperlでしかやらないなーってのはperlの方法だけ。

http://d.hatena.ne.jp/Yamashiro0217/20120727/1343371036

問1

% cat test.txt
% perl -pe '' test.txt

問2

% perl -aF, -pe '$_="$F[0],$F[3]"' test.txt

問3

% cat test.txt | grep ^server4
% perl -ne '/^server4/&&print' test.txt

問4

% cat test.txt | wc -l
% perl -ne 'eof&&print$.' test.txt

問5

% cat test.txt | sort -t',' -k1,1 -k3,3n | head -5
% perl -e 'print for map{join ",",@$_}sort{$a->[0]cmp$b->[0]||$a->[2]<=>$b->[2]}map{[split /,/, $_]}<>;' test.txt

問6

% cat test.txt | sort | uniq | wc -l
% perl -nE '!$m{$_}++&&$n++;eof&&say$n' test.txt

問7

% cat test.txt | cut -f3 -d, | sort | uniq | wc -l
% perl -aF, -nE '!$m{$F[2]}++&&$n++;eof&&say$n' test.txt

問8

% cat test.txt | cut -f4 -d, | sort | uniq -c | sort -nr | head -1
% perl -aF, -nle '$m{$F[3]}++;eof&&print join" ",@{(sort{$b->[0]<=>$a->[0]}map{[$m{$_},$_]}keys%m)[0]}' test.txt

問9

% perl -aF, -ple '$_=$F[0];s/server/xxx/' test.txt | sort | uniq -c
% perl -aF, -nlE '$_=$F[0];s/server/xxx/;$m{$_}++;eof&&say for map{"$m{$_} $_"}sort keys%m' test.txt

問10

% perl -aF, -nlE '$F[2]>9&&say$F[2]' test.txt | sort -n | uniq
% perl -aF, -nlE '$F[2]>9&&$m{$F[2]}++;eof&&say for sort keys%m' test.txt

投稿者 Songmu : 2012年7月28日 16:46

トラックバック

このエントリーのトラックバックURL:
http://www.songmu.jp/cgi-bin/mt/mt-tb.cgi/10