rubyをワンライナーなんかで使う時に
よく使うrubyコマンドのオプションとかグローバル変数等を中心にまとめました

グローバル変数

コンフィギュレーション系

  • $LOAD_PATH, $: : require時の検索対象パスの配列

IOストリーム、文字列処理系

  • $_ : 最後にgetsまたはreadlineで読み込んだ文字列
  • $< : コマンド行で指定されたファイルまたは標準入力へのIOオブジェクト、Kernel.gets等の読み出しはこれが使われる
  • $stdin : 標準入力ストリーム
  • $stdout, $> : 標準出力ストリーム、Kernel.puts、print、printf等の表示メソッドの出力先
  • $stderr : 標準エラー出力ストリーム
  • $FILENAME : 現在ARGFから読み出されているファイル名
  • $. : 現在の入力ファイルの最後に読み込んだ行番号
  • $/ : 入力レコードセパレータで、デフォルトは改行
  • $\ : 出力レコードセパレータで、デフォルトはnul、-lオプション時は$/と同じになる
  • $, : Array.joinのセパレータで、デフォルトはnil
  • $; : splitが使うセパレータで、デフォルトはnil、-Fオプション時は値を指定できる
  • $F : nまたはpオプションとaオプションを指定した時にsplitが返す値

正規表現系

  • $& : 現在のスコープで最後に成功した正規表現のパターンマッチ文字列
  • $~ : 現在のスコープで最後に成功した正規表現マッチオブジェクト
  • $` : 現在のスコープで最後に成功した正規表現マッチ文字列よりも前の文字列
  • $' : 現在のスコープで最後に成功した正規表現マッチ文字列よりも後の文字列
  • $+ : 現在のスコープで最後に成功した正規表現マッチのグループに対応する文字列

例外処理系

  • $? : 最後に終了したプロセスの終了ステータス
  • $! : 最後に発生した例外のオブジェクト
  • $@ : 最後に発生した例外のスタックとレース、$!.backtraceと同義

コマンドラインオプション

-e : [-e 'command']の形式でcommand文字列を実行する

    $ ruby -e 'p "hello!"'
    # -eオプション使用時はif等の条件式に単独の正規表現リテラルを
    # 記述した場合、暗黙的に$_との比較となる
    # 下の例はlsの結果のうち先頭がMの行を抽出
    $ ls | ruby -ne 'print if /^M/'    # printは引数無しの時は$_を出力する

-r : プログラムの実行前にrequire 'hogehoge'を行う

    $ ruby -r 'date' -e 'p DateTime.now'

-n :
awkっぽい感じ。
標準入力を1行ずつ取得し[$_]にセット。
その後、eオプションで設定した処理を実行する

    # ドットから始まるファイル、ディレクトリ名を抽出
    $ ls -a | ruby -ne 'print if /^\.\w+$/'

-p : 処理の最後に$_の値を出力する

$ echo "test abc" | ruby -pe '$_.upcase!'

-a : nまたはpと組み合わせて使うと各行がsplitされて$F変数に格納されてくる

# lsの結果のうち<bash>が含まれるレコードを抽出し、splitされた配列の
# 1番目と最後の列(権限とファイル名)を表示する
$ ls -al | ruby -ane 'p "#{$F[0]} : #{$F[-1]}" if /bash/'

使用例

例えばapacheのログをちょっと確認してみるケース。
ログの中から400系か500系のステータスのレコードを抽出し、
日付部分の不要な文字列を削除してhttpステータス URL アクセス日時を表示する
bashのコマンドでやるとこんな感じ

cat access_log | awk '{print $9,$7,$4}' | grep -P '^[45]\d{2}' | sed -e "s/\[//g"

これをrubyで置き換えるとこんな感じ

ruby -nae 'p "#{$F[8]} #{$F[6]} #{$F[3].gsub("[","")}" if $F[8] =~ /^[45]\d{2}/' access_log

個人的には一つの言語でワンライナーで書いた方が微妙な仕様の違いに惑わされなくて済むし、
使い捨てコードは後者を選択する事が多いかも。