LoginSignup
40
39

More than 5 years have passed since last update.

ワンライナーのための perl コマンドラインオプション入門

Posted at

perl とか学生時代にはじめて Web に触れたとき以来ほとんど触ったことありませんが、たまにワンライナーで sed の代わりにつかうと便利です。

大抵の環境でインストールされているし、python も大抵の環境でインストールされているけどワンライナーには向かないし。

コマンドラインオプションの説明

-e <program>

実行するスクリプトの内容を指定します。perl をワンライナーで使用するならこれは必須です。

-p

入力データの各行を処理して出力します。入力行は $_ に入ります。

概ね次のようなコードと同じです(イメージ)。

while (<>) {
  ... script ...
} continue {
  print;
}

-n

入力データの各行を処理します。-p から出力を取り除いたものです。

while (<>) {
  ... script ...
}

-l[octal]

スクリプトの処理前に行を chomp し、さらに print で出力時に改行を追加します。8進数で文字を指定すると print で出力時に追加される文字を指定できます。

-l を使わないかぎり $_ とか後述の $F の最後とかには改行も含まれています。sed や awk と同じ感覚で使うなら -l も付けておくと良いでしょう。

-0[octal]

8進数で行のセパレータ文字を指定します。省略すればヌル文字になります。

例えば find の -print0 と組み合わせて次のように使います。

find . -name '*.bak' -print0 | perl -0ne unlink

-a

-n-p と一緒に使用すると、スクリプトの実行前に行を分割して @F に代入します。

awk っぽい使い方ができます。

ip -o addr show | perl -anle 'print $F[3]'

-F<pattern>

-a で行を分割するときのセパレータを指定します。

cat /etc/passwd | perl -aF: -lne 'print $F[2]'

指定されたものは正規表現と解釈されます。

echo -e 'aaa123bbb\nccc456ddd' | perl -aF'\d+' -lne 'print $F[1]'

修飾子を付けて指定することもできます。

echo -e '12a34\n56Z78' | perl -aF'/[a-z]/i' -lne 'print $F[1]'

-i[extension]

入力ファイルを処理結果で上書きします。extensionを指定すると元ファイルに拡張子を付与してバックアップします。

sed の -i と同じです。

perl の補足

perl はいろんなところで変数が省略できるようになっており、下記のコードだと、

while (<>) {
  ... script ...
} continue {
  print;
}

下記のコードと同じです(たぶん)。

while ($_ = <>) {
  ... script ...
} continue {
  print $_;
}

他の制御文とかでも、変数を省略すると自動的に $_ が使われます。

例えば、下記のコードは、

print if /foo/

下記のコードと同じです(たぶん)。

print $_ if $_ =~ /foo/

普通にコードを書く分には気持ち悪いことこのうえないですが、ワンライナーするには便利です。

使用例

てきとうな入力データを作ります。

cat <<EOS> hoge.log
foo123bar,ore,,123
foofoo456,are,,456
barbar789,sore,,789
EOS

foo を ___ に置換します。もちろんこの程度なら sed でも余裕です。

# sed の場合
cat hoge.log | sed 's/foo/___/g'

# perl の場合
cat hoge.log | perl -pe 's/foo/___/g'

正規表現に一致する最初の行を表示します。これも sed でも余裕です。

# sed の場合
cat hoge.log | sed -rn '/are/{p;q}'

# perl の場合
cat hoge.log | perl -lne 'print,exit if /are/'

正規表現に一致する部分文字列を返します。grep で一応できます。

# grep の場合
cat hoge.log | grep -Po 'foo\d+'

# perl の場合
cat hoge.log | perl -lne 'print $1 if /(foo\d+)/'

正規表現のサブパターンだけを返します。たぶん sed や grep だと辛いです。

# perl の場合
cat hoge.log | perl -lne 'print $1 if /foo(\d+)/'

区切り文字で分割した2番目の項目を出力します。これは awk でも余裕です。

# awk の場合
cat hoge.log | awk -F, '{print $2}'

# perl の場合
cat hoge.log | perl -aln -F, -e 'print $F[1]'

正規表現で分割した2番目の項目を出力します。たぶん awk だと辛いです。

# perl の場合
cat hoge.log | perl -aln -F'/,+/' -e 'print $F[2]'

ruby のワンライナーのためのコマンドラインオプション

実は ruby にもほとんど同じようなコマンドラインオプションがあります。

40
39
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
40
39