perl のワンライナーの初歩 #3

  • 2
    いいね
  • 0
    コメント

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行おきにある一定の形式が繰り返されるファイルがある

fastqもどき
@名前
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{}