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


perl のワンライナーに関しての、適当な解説 [#1](http://qiita.com/bunzaemon/items/fdb1115ac97fc0955236)/#2/[#3](http://qiita.com/bunzaemon/items/efcb3f20329bc68bb8bc)/#4

##### まず
公開前に、他のスニペットストックを見返して、あまりにも不親切なので、本当に、ざっとした解説を書こうかと思った。その2。


[ここ](http://perldoc.jp/docs/perl/5.20.1/perlrun.pod)を読めって内容ですけど。


## -0
|オプション|意味|
|:--|:--|
|-0|ヌル文字区切りで読み込む。|
|-00|ファイルを段落毎読み込みする。|
|-0777|ファイルを丸呑みする|



段落読みは（ちょっと工夫が必要だけど） clustalw 形式のアライメント出力を読み込む時に良い

'B=Deparse' を利用して、何をしているかを表示してやる。

```bash:
$ perl -MO=Deparse -0 -lane 'print'
BEGIN { $/ = "\n"; $\ = "\000"; }
LINE: while (defined($_ = <ARGV>)) {
    chomp $_;
    our(@main::F) = split(' ', $_, 0);
    print $_;
}
```
わざわざ diff 取る必要もないけど、、、

```bash:
$ diff <(perl -MO=Deparse -0 -lane 'print' ) <(perl -MO=Deparse -00 -lane 'print' )
1c1
< BEGIN { $/ = "\000"; $\ = "\000"; }
---
> BEGIN { $/ = ""; $\ = "\n\n"; }
$ diff <(perl -MO=Deparse -0 -lane 'print' ) <(perl -MO=Deparse -0777 -lane 'print' )
1c1
< BEGIN { $/ = "\000"; $\ = "\000"; }
---
> BEGIN { $/ = undef; $\ = ""; }
```

[bash](http://linuxjm.sourceforge.jp/html/GNU_bash/man1/bash.1.html), zsh のプロセス置換は、良いです。

## -a
`-p(n)` 適用時。
自動的に `$_` を `split (' ')` して、`@F` にセットする。
>コマンドラインツール awk のデフォルトの振る舞いをエミュレートします。
[引用元](http://perldoc.jp/func/split)

なので注意が必要です。


## -F
`-a` 適用時の区切り文字を指定出来ます。
`split /REGEX/` の REGEX 部分だと考えて良いので、正規表現で指定してやるのが吉です。


### 例

|オプション|利用方法|
|:--|:--|
|-F'\t' -lane|タブ区切りテキストを開く|
|-F',' -lane|CSV を開く|
|-F'>' -0777 -ne|ファスタ毎に split（'>' 除く）|
|-F'(?=>)' -0777 -ne|ファスタ毎に split（'>' 残す）|
`>` で split した場合には、`@F` の最初の要素にノイズが残る
`(?=>)` これは正規表現における先読み言明。上述のノイズの心配は無い

### 先読み後読み言明
[ここ](http://blog.livedoor.jp/dankogai/archives/50820912.html)を読むべきでしょう。
bioinformatics 的には、上記 fasta のスプリットや、制限酵素断片の算出など色々な所で使える。後々のコード随所に現われる

## -M/-m
モジュール読み込み

```bash:
$ perl -Mstrict -Mwarnings -lne '...'
```
などとして使う
なお、違いは、

```bash:-Mでは出来るよ
$ perl '-Mvars qw(@a)' -lne '...'
$ perl -M'vars qw(@a)' -lne '...'
```
出来るか出来ないかだけの模様
普通に `-mvars='@a'` 出来るんだから、必要無いよ、この差

### no モジュール

消すのもアレなので残しておくが、
[思いの外実用性が無い事が判明したので、覚える必要は無い。](http://qiita.com/bunzaemon/items/7bacbd3a9f8ce9c22c3c)

`-M` + `-` + モジュール名で `no` を指定出来る。

例えば、`no warnings qw(newline)` を明示的に指定したい場合。

```
$ perl -M-warnings=newline  -e 1
```


## 変数宣言
```bash:
export PERL5OPT='-Mstrict -Mwarnings'
```

している諸兄も多いだろう中、ワンライナーを書こうとすると変数宣言で問題になる事がある。

普通に、`use vars` して対応。

```bash:
$ perl -Mvars='@a' -lne '...'
```

初期値を入れたい場合には、

```bash:
$ perl -Mvars='@a' -lne 'BEGIN{ @a = 1 .. 10} '
```

## PERL5OPT

オプションを予め指定する環境変数です。上述の様に strict, warnings を効かせる他に、

* Data::Dumper
* Storable

などを有効にしとくと便利

### 例えば、
```bash:
$ export PERL5OPT='-MStorable=nstore,retrieve -MData::Dumper'
```
しとけば、

```bash:
$ perl -le 'nstore {qw(foo bar)} , q{test.db}' 
```
hash などをちょっと保存して、、

```bash:
$ perl -le 'print Dumper retrieve q{test.db}'
$VAR1 = {
          'foo' => 'bar'
        };
```

他のワンライナーから、さくっと利用する事が可能
`Dumper` は Data::Dumper より

### B::Deparse

`-0` の項の例にある通り -MO=Deparse` を付けて確認するのは常識。

もっと知りたければ `perldoc B::Depase` して下さい。
何で、'B::' で何で、 `-MO=` なのかは[ここ](http://perldoc.jp/docs/perl/5.14.1/perlcompile.pod#Layout)

```bash:
$ perl -MO=Deparse -0 -lane 'print' > SOMETHING.pl
```

などとして、ワンライナーで仮スクリプトを作成した後に、本スクリプトの雛形に用いるのも良い。


[次回](http://qiita.com/bunzaemon/items/efcb3f20329bc68bb8bc)へ。