Hatena::ブログ(Diary)

ablog このページをアンテナに追加 RSSフィード Twitter

2015-07-11

Perlワンライナー集

障害解析のためのログの調査、非互換対応でのソースコードの調査といったテキスト処理で使った Perl ワンライナー集です。

マルチライナーやいけてないのもありますw



Perl ワンライナーの良いところ

  • PerlOracle Database (10g以降) に同梱されている。従って、Windows プラットフォームでも使える。
  • awksedgrep正規表現の書き方などをそれぞれ覚えれない。awksedgrep でできることはだいたい Perl でできるので、Perl に絞ると覚えることを減らせる。
  • 最小限の労力で最大限の仕事ができる。ちょっとしたプログラムを書くような処理でも Perl ワンライナーを使うとたった1行で済むことがあります。

Perlワンライナー

※一部、Perl 以外に bash、find、xargs なども含んでいます。
 
・レコードセパレータを変更する
perl -wple ...       # 行モード(デフォルト)
perl -00 -wle ...    # 段落モード(1つ以上の空行をレコードセパレータと認識する)
perl -0777 -wle ...  # ファイルモード(ファイル全体を1レコードとして認識する)

・カスタムフィールドセパレータを使う(改行コードをフィールドセパレータとする)
perl -00 -F'\n' -lane 'print $F[1] if($F[0] =~ /neo/)' hoge.txt

・テキストファイルの特定の行だけ表示する 
perl -lne 'print if $.<2' file  # 1行目だけ表示する
perl -pe 'exit if $. > 10' file # 10行目まで表示する
perl -ne 'print if 2.. 5' file  # 2行目から5行目まで表示する

・CSV の列数をカウントする
perl -F, -lane 'printf("%s:%d\n",$ARGV,$#F);$.>0 and close ARGV' *.csv

・CSV の任意の列のみ抽出する(1列目、3列目、11列目以外を抽出する)
perl -F, -lane 'print join(",",@F[1,3..9,11..$#F])' *.csv

・ファイル中の空行を削除する
perl -i.org -ne '/^\s*$/ or print' test.sql

・ダブルクオートをシングルクオートに置換する
perl -ple 's/\"/\'/g' hoge.csv

・「ORA-」メッセージをエラー番号別に集計する
perl -nle 'BEGIN{%h=();}/(ORA-[0-9]+)/ and $h{$1}++;END{map{print qq/$_:$h{$_}/} keys %h;}' alert_orcl.log

・Java アプリケーションのログから発生した Exception の回数を集計する
perl -wnle 'BEGIN{%h=();}/([a-zA-Z]*Exception)/ and $h{$1}++;END{map{print "$_:$h{$_}"} sort keys %h;}' *.log

・リスナーログから接続元ホスト毎に接続回数を算出する
perl -nle 'if(/(\d{2}-\w{3}-\d{4} \d{2}:\d{2}:\d{2}).*CONNECT_DATA.*HOST=([\w\-\.]+).*HOST=([\w\-\.]+)/i){$h->{qq/$2,$3/}->{count}++;$h->{qq/$2,$3/}->{date}=$1};END{map{print qq/$_,$h->{$_}->{count},$h->{$_}->{date}/} keys %$h}' listener.log

・再帰的にファイル名に接頭辞をつける
perl -MFile::Find -e 'find sub{rename($_,"prefix_$_") if -f}, @ARGV' .

・テキストファイル中の最長行の文字数を求める
perl -nle '$a=length if($a<length);END{print $a}' orcl_ora_879.trc 
perl -MList::Util=max -lne 'push(@a,length);END{print max(@a)}' orcl_ora_879.trc 

・あるディレクトリ以下のファイルを再帰的に検索して文字コードを調べる
perl -0777 -MEncode::Guess -wne '$e=guess_encoding($_,qw/euc-jp shiftjis 7bit-jis/);print "$ARGV:".$e->name."\n" if(ref($e))' **/*
 
・任意のディレクトリ配下にどのような拡張子のファイルがどれだけあるか集計する
perl -MFile::Find -MFile::Basename -e 'find sub{$h{(fileparse($_,qw{\.[^\.]+$}))[2]}++ if -f},@ARGV;END{map{print "$_:$h{$_}\n"}keys %h}' .

・2つ以上の空白文字は1つにするがシングルクオートで囲まれたリテラルは無視する 
perl -pe 's/\G((\x27[^\x27]*\x27[^\x27]*?)*[^\x27]*?)[ ]+/$1 /g' foo.c

・レコードセパレータが1つ以上の空行で、レコード内に改行文字を1つ含むデータを1行1レコードに変換する
perl -i.org -00 -pe 's/^(.*)\n(.*)\n+$/$1 $2\n/' aaa.txt

・1ファイル中に「DECODE」と「DISTINCTまたはUNIQUE」を含みかつ「ORDER BY」を含まないファイルをリストアップする
find . -type f -print0|xargs -0 perl -0777 -nle '/decode/i and /distinct|unique/i and !/order\s*by/i and print qq/$ARGV:$./;eof and close ARGV'

・find + xargs + Perl ワンライナーでシェルスクリプトのシェバンの次の行に1行追加する
find . -type f -name '*.sh' -print0|xargs -0 perl -i.org -0777 -pe 's/(\s*#![\w\s\/]+\/bash)/$1\nexport LANG=C\n/'

・ASCIIコードを文字に変換する
perl -e 'map{print chr($_)} @ARGV' 112 101 114 108  # ASCIIコードが10進数の場合
perl -e 'map{print chr(hex($_))} @ARGV' 70 65 72 6C # ASCIIコードが16進数の場合

・メモリを大量消費する 
perl -e 'while(1){$i++;$h{$i}=$i}' 
 
・CPU使用率を 100% にする 
perl -e 'while(1) {}'
  
・CPU使用率を 100% にする(4コアを使う)
for i in {1..4}
do
perl -e 'while(1){}' &
done

<2012/06/07 追記>
・iostat の出力結果を特定の列でソートする
 この例では、デバイスを sdk だけに絞って、%util(11列目) でソートしています。
perl -lane '/^sdk/ and push(@tmp,[@F]);END{map{print join(qq/ /,@{$_})}sort{$a-[11]<=>$b->[11]}@tmp}' iostat.log

・V$SYSSTAT から特定のデータベース統計情報の差分を出す
perl -F, -lane '/global cache blocks lost/ and printf(qq/%s,%s\n/,$F[0],$F[2]-$tmp) and $tmp=$F[2]' sysstat.log

・V$SYSSTAT から特定の統計に絞らずにデータベース統計情報の差分を出す
% perl -F, -lane 'printf(qq/%s,%s,%s\n/,$F[1],$F[0],$F[2]-$h{$F[1]})if(exists($h{$F[1]}));$h{$F[1]}=$F[2]' sysstat.log

・vmstat の出力結果から時間帯毎のCPU使用率を算出する
perl -lane '$.>2 and @t=split(q/:/,$F[1]) and $h->{$t[0]}->{sum}+=$F[21]+$F[22] and $h->{$t[0]}->{cnt}++;END{map{printf(qq/%02d\t%.1f\n/,$_,$h->{$_}->{sum}/$h->{$_}->{cnt})}sort keys %$h}' vmstat.log

<2014/5/31 追記>
・top の行頭に時刻を追加
perl -ne '/^top - (\d\d:\d\d:\d\d)/ and $t=$1;print qq/$t $_/' top.log > top_time.log

・2行にまたがっている iostat のログを1行にする
perl -pe '/sssn[0-9]+s:/ and chop' iostat.txt > iostat_tmp.txt
perl -pe 's/(sssn[0-9]+s:[\/\w]+)iostat\s[0-9\/]{10}\s[0-9:]{8}/$1/' iostat_tmp.txt > iostat_mod.txt

・ファイルの文字コードを変換する
perl -i -MEncode -pe 'Encode::from_to($_,"utf8","shiftjis");' *.txt"

・ファイル名一括置換
perl -0777 -ne '$o=$ARGV;$ARGV=~s/\s/-/g;rename($o,$ARGV);' *.jpg

<2015/3/3 追記>
・16進数から10進数に変換
perl -e 'map{print hex($_)} @ARGV' 4a98

・10進数から16進数に変換
perl -e 'printf qq/%X/, 19096'

・中途半端にCPU使用率を上げる
perl -MTime::HiRes -e 'while(1){for(1..10000){};Time::HiRes::sleep(0.0001)}'

・strace をグラフ化するために加工する
perl -lane '$F[2]=~s/^([a-z]+).*/$1/; $h->{$F[1]}->{$F[2]}++;END{map{$t=$_ and print $t;map{print qq/$t\t$_\t$h->{$t}->{$_}/} keys %{$h->{$_}}} keys %$h}'' strace.log

・top を時系列・PID別にグラフ化するために加工する
grep -hA 20 '^top -' top.logperl -lane '/top - ([\d:]+)/ and $t=$1;$F[0]=~/\d+/ and printf (qq/%s %s%s\n/,$t,$_,lc(sprintf(q/%X/,$F[0])))'

参考


関連

スパム対策のためのダミーです。もし見えても何も入力しないでください
ゲスト


画像認証

トラックバック - http://d.hatena.ne.jp/yohei-a/20150711/1436623390
リンク元