【Ruby上級】Rubyワンライナーを使いこなしたい

Rubyの記事を漁っていたら、いつの間にかワンライナーの記事を読んでいたので、復習&記憶用に記事を執筆しておきます。

Rubyにも便利なオプションがあって、いつか何かの役に立ちそうなのでその理解andまとめをしておこうかなと思います。

[]ad#co-1]

ワンライナーとは

そもそもワンライナーが何か知らない人のために。ワンライナー「One Liner」とはその名の通り「たった一行のコード」の総称です。言語によっては一行でかなりのタスクをこなすことができ、オプションや引数によってその組み合わせは無限大です。エディタを起動するまでもないプログラムの作成等にワンライナーが良く使われます。

「ワンライナー」とは、たった1行だけのプログラムです。PerlやRubyを使うと、1行だけでもかなりの仕事ができます。 プログラムを書きたいが、エディタを起動するほどの手間はかけたくない、というときに威力を発揮します。達人ともなると、ちょっとした文字置換や計算をするワンライナーを、即興で作って使い捨てることもあります。PerlやRubyは、ワンライナーを書くために役立つオプションを豊富に持っています。[-Hatena Keywordより]

 Rubyのワンライナーオプション

上にも書かれているように、Rubyにはワンライナーを作るために必要な非常に便利なオプションが標準で用意されています。

-eオプション

Rubyワンライナーを記述するにあたって最も基本的なオプションになります。引数にとったスクリプトを実行するだけのシンプルなオプションです。

$ ruby -e 'puts "basic option"'

このコマンドで「basic option」と出力されます。

-nオプション

プログラム全体が「while gets ~ end」という while ループで囲まれる様に動作するオプションです。実際に動作を確かめてみます。

まずはこのようなテキストファイルを用意します。

1行目
2行目
3行目

次に、以下のコマンドを打ちます。

$ ruby -ne 'puts $_' test.txt
1行目
2行目
3行目

このようにコマンドを打つことでtest.txtのファイルの内容が一行ずつ出力されました。

これは、以下のコマンドと同義だそうです。

$ ruby -e 'while gets; puts $_; end' test.txt

これを見ても初めて見る人はおそらく流れが理解できないと思いますので少し分解して解説していきます。

Rubyだけを勉強してきた人はセミコロンを書く記述に慣れてないと思いますが、実際の文法的には区切ることを明示的にするためにセミコロンを書く記述方法もRubyにはあります。一般的ではないだけです。これを利用してワンライナーのコードを拡張することができます。

while getsのgetsはKernel.#getsのgetsです。Kernel.#getsとは、「ARGFから一行読み込んで、それを返す」というKernelモジュールです。Kernelモジュールとは、Rubyの組み込みライブラリの一種のことです。

ARGFという見慣れない単語がありますがこれも組み込みライブラリの一種で、「スクリプトに指定した引数をファイル名とみなして、それらのファイルを連結した1つの仮想ファイルを表すオブジェクト」として定義されています。簡単に説明すると複数のファイルを1つのファイルに変換した仮想オブジェクトであるというイメージです。より詳しく知りたい方はリファレンス等を参考にすると良いでしょう。

ここまで理解できれば残るは「$_」が何を表しているかを知るのみです。ここにはgetsで取ってきたオブジェクト(文字列)がセットされます。ちなみに「$_」はRubyに標準搭載されている組み込み変数です。Kernel.#getsもしくはKernel.#readlineから読み込んだ文字列がセットされます。

大まかな流れをまとめると、

①test.txtをARGFとして定義⇨

②ARGFからgetsで一行ずつ文字列を取得⇨

③取得した文字列を組み込み変数の「$_」にセットして出力

という流れです。

-pオプション

nオプションとほぼ同じですが、1つだけ異なる点があります。それはprintメソッドを省略できるということです。すなわちプログラム全体をwhile gets ~ endして、さらに各ループの最後にprintを加えます。

$ ruby -pe '' test.txt (test2.txt)
$ ruby -ne 'puts $_' test.txt
$ ruby -ne 'print' test.txt
$ ruby -e 'while gets; puts $_; end' test.txt

上の4つのコマンドは全て同義です。これらの4つを理解してオプションの動きを把握しましょう。

-aオプション

オートスプリットをするオプションです。-nオプションと-pオプションと併用して使います。

各ループの先頭で $F = $_.split を実行します。

例:カレントディレクトリの情報を配列にして表示する

$ ls -laF | -ane 'p $F'
["total", "8"]
["drwxr-xr-x", "3", "tatsuya", "staff", "96", "9", "30", "14:02", "./"]["drwxr-xr-x", "4", "tatsuya", "staff", "128", "9", "30", "14:01", "../"]
["-rw-r--r--", "1", "tatsuya", "staff", "24", "9", "30", "14:02", "test.txt"]</span>

-Fオプション

splitのデフォルト区切り文字を設定するオプションです。文字列を分割したい時に便利。

例:環境変数PATHを:で分割して改行して表示する

$ echo $PATH | ruby -F: -ane 'puts $F'

-rオプション

ライブラリを読み込むオプションです。例えばこのサイトのページのソースを取得したい場合

$ ruby -r open-uri -e 'open("https://ty-engineer.com") { |f| puts f.read }

とするとopen-uriライブラリを読み込んでページを取得できます。

複数のライブラリを読み込みたい場合、一つずつ-rオプションをつける必要があります。

おわりに

Rubyのワンライナーを作成するための基礎的なオプションの知識を整理してみました。これ使いこなせたらターミナルからちょちょっとちょっとした作業ができそうなので暇な時にマスターしておきたい知識です。

この記事を作成するにあたってこちらの記事が非常に役に立ちました。@maeharinさんに感謝。

Rubyのワンライナーについての記事は割と少なかった気がするので、この記事が誰かの役に立てれば幸いです。僕もワンライナー目指して頑張るぞ()。他のコマンドもたくさん覚えなky…

Ruby中級者にはこちらの書籍をオススメしています。もしまだ読んでいない人がいれば是非読んでみて下さい。

スポンサードリンク

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です