Skip to content

Instantly share code, notes, and snippets.

@yoheia
Last active August 26, 2024 05:55
Show Gist options
  • Save yoheia/9717788 to your computer and use it in GitHub Desktop.
Save yoheia/9717788 to your computer and use it in GitHub Desktop.
Perlワンライナー&マルチライナー集
Perl ワンライナーサンプル集
■概要
障害解析のためのログの調査、非互換対応でのソースコードの調査といった
テキスト処理で使った Perl ワンライナーのサンプル集です。
Perl ワンライナーは以下の点が良いと思います。
・Perl は Oracle Database (10g以降) に同梱されている。
 従って、Windows プラットフォームでも使える。
・awk、sed、grep の正規表現の書き方などをそれぞれ覚えれない。
 awk、sed、grep でできることはだいたい 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/05/20 追記>
・top の行頭に時刻を挿入する
perl -ne '/^top - (\d\d:\d\d:\d\d)/ and $t=$1;print qq/$t $_/' top.log > top_time.log
<2014/08/11 追記>
・半角数字以外の文字を除去する
perl -ple 's/[^0-9]//g' list.txt
<2014/08/30 追記>
・ORA-4031発生時に出力されるトレースの”Memory Utilization of Subpool”のセクションをCSV化する
perl -F\" -lane '/\*{3} ([0-9\-\.:\s]+)/ and $d=$1;/^Memory Utilization of Subpool ([0-9])/ and $n=$1;/^\"/ and $#F==2 and print qq/"$d","$n","$F[1]","$F[2]"/' *.trc
・V$SQLを spool したログから特定の SQL Id の特定列のみ抽出する
perl -F\^ -lane '/SQLID/ and print qq/@F[0,1,2,3]/' sql.log
<2014/09/16 追記>
・ORA-4030のトレースファイルから領域ごとのメモリ使用量を調べる
perl -nle '/End of process map dump/ and exit;/Dumping process map/ and $b=$.+1;defined($b) and $.>$b and print;'
foo.trc > process_map_dump.txt
perl -lane '($b,$e)=split(/-/,$F[0]);printf(qq/$.\t%s\t%d\n/,$F[5],(hex($e)-hex($b))/1024)' process_map_dump.txt > process_map_size.txt
・V$SQL_SHARED_CURSOR を加工する(1レコードが2行で出力されているので1列に変換し、特定のSQLで絞り込む)
perl -i.org -ple 's/\s+$//g' cursor.log
perl -00 -nle '/^SQLID/ and s/\n+/ /g and printf(qq/%s\n/,$_)' cursor.log > cursor_mod.txt
・16進数から10進数に変換
perl -e 'map{print hex($_)} @ARGV' 4a98
・10進数から16進数に変換
perl -e 'printf qq/%X/, 19096'
・strace のログを日時、PID、特定システムコールのコール回数に加工
perl -lane '/futex/ and $h->{$F[1]}->{$F[0]}++;END{map{$t=$_;map{$p=$_;print qq/$t:$p:$h->{$t}->{$p}/} keys %{$h->{$_}} } keys %$h}' strace.log
■参考
・404 Blog Not Found: perl - ワンライナーの書き方入門
http://blog.livedoor.jp/dankogai/archives/51026593.html
・ミニマルPerl ―Unix/LinuxユーザのためのPerl習得法
http://www.amazon.co.jp/%E3%83%9F%E3%83%8B%E3%83%9E%E3%83%ABPerl-%E2%80%95Unix-Linux%E3%83%A6%E3%83%BC%E3%82%B6%E3%81%AE%E3%81%9F%E3%82%81%E3%81%AEPerl%E7%BF%92%E5%BE%97%E6%B3%95-Tim-Maher/dp/4873113687
■変更履歴
2012/06/07 「iostat の出力結果を特定の列でソートする」など4件追記
2011/06/02 「リスナーログから接続元ホスト毎に接続回数を算出する」を修正
2011/06/02 「1ファイル中に「DECODE」と「DISTINCTまたはUNIQUE」を含みかつ「ORDER BY」を
含まないファイルをリストアップする」を修正。perl に -0777 オプション追加。
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment