perl のワンライナーに関しての、適当な解説 #1/#2/#3/#4
頻繁に使う特殊変数など
について書いとくべきか。重複しての説明が増えるけど
当然、こことか、こことかには目を通すべき
$ARGV
今開いてるファイル名を収納
ループを抜けても、初期化はされないので
$ perl -lne '}{ print $ARGV' SOMETHING.txt
などとする事も
$.
ファイルハンドルのライン番号を表示
$ perl -lne 'print $.' SOMETHING.txt
すればインクリメントするのが分かる。
- ワンライナーでなくとも
while(<$fh>){ print $. }
的に出番は多い。 - ワンライナーの、
-n(p)e
で複数ファイルを扱う場合。ファイルハンドルを開き直してない- => トータルのライン番号を表示する、、、
eof FILEHANDLE
EOF の判定、ここ読め
- ワンライナー
-n(p)e
的にはeof
で、複数ファイルそれぞれの末尾を判定 -
eof()
の存在は地雷なので忘れる。 - もしくは、明示的に
eof ARGV
などと、、、
と言う事で、上記 $.
のリセットなどにも使う
$ perl -lne 'print join qq{\t}, $ARGV, $. ; $. = 0 if eof' SOME.txt THING.txt
BEGIN{}
最初に処理を行なう特殊ブロック
-n(p)e
で、どうしてもループ開始前に処理がしたい場合などに使う
END{}
最後に処理を行なう特殊ブロック
}{
の方がタイプ数が少ないから、そっちを使ってしまうが、好みの問題
$,
リストのプリントのセパレータ設定
つうことで数行上のワンライナーは、
$ perl -lne 'BEGIN{ $, = qq{\t} } print $ARGV, $. ; $. = 0 if eof' SOME.txt THING.txt
こうも書ける
%
二項演算子としては剰余を返す
ワンライナー的には行における挙動制御の重要な演算子
例えば、4行おきにある一定の形式が繰り返されるファイルがある
@名前
ACGTACGTACGTACGT
+
IIIIIIIIIIIIIIII
名前の行だけ取り出したければ、
$ perl -lne 'print if $. % 4 == 1 ; ' SOMETHING.txt
だし、名前と塩基配列を取り出したければ、
$ perl -lne 'print if ( $. - 1 ) % 4 <= 1 ; ' SOMETHING.txt
だ。
三項演算子
三項演算子は通常のスクリプトで使用するのには、否定的な人も多い
しかし、ワンライナー的には非常に重要になってくる
(条件) ? 真の時の値 : 偽の時の値
例えば、ファイルハンドルを切り替えたりするのに、一々 if~else
を書いてはいられない
$ perl -lne 'print { ( $. - 1 ) % 4 <= 2 ? *STDOUT : *STDERR } $_' SOMETHING.txt > /dev/null
範囲演算子
スカラコンテキストでの範囲演算子の利用も重要だ
条件1 .. 条件2
定型文章の切り出しには欠かせない。
例えば前述の 'fastqもどき' 書式の名前から'+' 行まで切り出すのならば、
$ perl -lne 'print if /^\@/ .. /^\+/ ' SOMETING.txt
- もちろん現実の FASTQ に適用してはならない。
- qual 列先頭に '@' が(ついでに '+' も)出現する可能性があるから
2行目から5行目を切り出すには、
$ perl -lne 'print if 2 .. 5' SOMETING.txt
20151015 | 追記
自分で perldoc へのリンクを貼っておきながら、つい最近まで、E0
の活用をしていなかった事に気付く。
マルチファスタからシーケンスを引っ込ぬくのは、
$ perl -lne 'next if ! ( $a = />gi\|STR/ ... />/ ); last if $b and />/; print ; $b = $a' MULTIFASTA
って書いてたけど、
$ perl -lne 'next if !($a = />gi\|STR/ ... />/ and $a !~ /E0$/ ); print' MULTIFASTA
で良い。
クォート
ワンライナー中に限らず、視認性やタイプのしやすさから、クォートには別表記が存在する
表記 | 別記 |
---|---|
'' | q{} |
"" | qq{} |
`` | qx{} |