Rubyでワンライナーを書く際によく使うコマンドライン引数と具体例をまとめてみた.
基本
-e : コマンドラインからスクリプトを指定
コマンドラインからスクリプトを指定する場合に使う.ワンライナーでは必須.
$ ruby -e 'puts "Hello, world!"'
行単位の処理
-n : 各行ごとに処理
プログラム全体が以下のwhileで囲まれているように動作する.
while gets ... end
標準入力やファイルの各行に対して処理を行いたい場合に便利.getsの結果は$_に格納される.
$ ruby -ne 'puts $_ if $_.include?("mickey24")' foo.txt
-p : 各行ごとに処理&出力
-nとほぼ同様だが,各ループの最後で
print $_
が実行されるようになる.標準入力の各行に対して処理を行いつつ出力していく場合に便利.
$ ruby -pe '$_.upcase!' foo.txt
-l : 入力&出力の改行文字の自動処理
以下の2つの効果がある.
- $\が$/と同じ値になる.つまりprintの出力結果の末尾にgetsの行区切り文字(デフォルトは改行文字"\n")が付くようになる
- -nや-pがセットされている場合,getsで読み込まれた各行に対してString#chop!が呼び出される
getsで読み込んだ$_の末尾に"\n"が付いてほしくない時や,-pで出力される文字列に自動的に"\n"を付けてほしい時に使うとよさげ.
-a : オートスプリットモード
-nや-pと組み合わせて使う.オートスプリットモードがオンになり,各ループの先頭で
$F = $_.split
が実行されるようになる.
$ ruby -aple '$_ = $F.join(",")' foo.tsv
-aを使う場合は-lも組み合わせて使う方がいいだろう(-lがないとsplit結果の最後の要素にだけ改行文字が付いてしまう).
-Fregexp : splitの区切り文字の変更
入力フィールドセパレータ($;)にregexpを代入し,splitでデフォルトで使われる区切り文字を変更する.-aと組み合わせると便利.
$ ruby -F, -aple '$_ = "#{$F[0]}, #{$F[2]]}"' foo.csv
その他
-r feature : require
スクリプト実行前にfeatureをrequireする.
$ ruby -r base64 -e 'puts Base64.encode64("mickey24")'
-Kc : エンコーディングの設定
外部エンコーディングとスクリプトエンコーディングを設定する.指定できるエンコーディングは以下の通り.
- -Ke : EUC-JP
- -Ks : Windows-31J, CP932
- -Ku : UTF-8
- -Kn : ASCII-8BIT, BINARY
$ ruby -Ku -e 'puts "うさみみ"'
-i[extension] : 入力ファイルの上書き
入力ファイルを出力結果で上書きする.
$ ruby -i -pe '$_.gsub!("\r\n", "\n")' foo.txt
元のファイルを残しておく場合は-iの直後に拡張子を指定する.以下の場合は元のファイルがfoo.txt.bakとして保持される.
$ ruby -i.bak -pe '$_.gsub!("\r\n", "\n")' foo.txt
コマンドライン引数まとめ
-e | コマンドラインからスクリプトを指定 |
---|---|
-n | 各行ごとに処理 |
-p | 各行ごとに処理&出力 |
-l | 入力&出力の改行文字の自動処理 |
-a | オートスプリットモード |
-F | splitの区切り文字の変更 |
-r | require |
-K | エンコーディングの設定 |
-i | 入力ファイルの上書き |
具体例
foo.txtの各行に行番号を付けて標準出力に出力する.
$ ruby -ne '$l ||= 1; puts "#{$l}: #{$_}"; $l += 1' foo.txt
foo.txtの各行の"\r\n"を"\n"に置き換え,foo.txtを上書きする.
$ ruby -i -pe '$_.gsub!("\r\n", "\n")' foo.txt
ユーザ"mickey24"が保持するプロセスのIDを標準出力に出力する.
$ ps aux | ruby -anle 'puts $F[1] if $F[0] == "mickey24"'
カンマ区切りのfoo.csvの3列目が24以上の行のみ標準出力に出力する.
$ ruby -F, -anle 'puts $_ if $F[2].to_i >= 24' foo.tsv
以上
-n,-p,-aあたりが使えるようになると劇的にワンライナーを書きやすくなるので,是非マスターしておきたい.
ここで挙げたRubyのコマンドライン引数はPerlのそれとほぼ同じなので,これらのことを覚えておけばPerlでもワンライナーが書けるようになると思う.