Rubyでもワンライナーを作れるのをご存じでしょうか。テキストで直すのは面倒だけど、プログラムを組んで処理するほどではないようなテキストファイルの変換は、コマンドの組み合わせでさっと済ませてしまいましょう。そしてRubyによるワンライナーならLinuxのコマンドの組み合わせよりも、いろいろなことが可能です。
今回はターミナルで使えるRubyによるワンライナーの作り方について紹介します。
ワンライナーとは
Webシステムの本番サーバーや開発機がLinuxの場合、ターミナルで短いコマンドを打ち込むだけで、面倒な処理をこなせる方がいます。ワンライナーとは、そのようないかにも職人と呼べるエンジニアが知っている、1行で複雑な処理ができてしまうコマンドの組み合わせです。
次からこのようなワンライナーの概要について紹介します。
ワンライナーの意味
ワンライナーは、英語の「one liner」のことで、一般的には一発ギャグという意味で使われますが、IT用語の「one liner」は1行で作られたコマンドの組み合わせや簡単なプログラムをさす言葉です。
1行にする理由は、Linuxのターミナルなどのコマンドラインから、キーボードでコマンドを打ち込んで実行するためです。そしてワンライナーは、Linuxが登場する前のUNIXの時代から使われていました。
例えばLinuxのシェルを使うとターミナルでコマンドを実行した結果は、パイプを介して別のコマンドに入力できます。このような1行程度で実行できるシェルの機能とコマンドの組み合わせがワンライナーです。
ワンライナーは難しい?
ワンライナーを使いこなすためには、やりたいことのために使えるコマンドやシェルの機能を知らなければなりません。しかも何も見ないでキーボードから正しいコマンド名を打ち込んだり、そのコマンドのオプションが使えるようになるには、そのコマンドを何度も使うといった経験が必要です。
そのためワンライナーを使いこなしているのは、大抵ベテランのエンジニアです。しかし難しいことはありません。よく使うコマンドとそのオプションの組み合わせは限られています。むしろ自分がやりたいことを、簡単な処理の組み合わせに分解して、それをコマンドにあてはめる、プログラミングの基本能力が求められる作業です。
ワンライナーでプログラムを使う
Linuxのターミナルで使えるワンライナーは、Linux用のコマンドとシェルの機能のみ、ということはありません。標準入力と標準出力が使えるアプリケーションであれば、ワンライナーに組み込んで利用できます。
例えばかつてUNIXで使われ、今のLinuxでも使えるawkコマンドは、C言語と似たようなプログラムが使えるコマンドです。このawkコマンドを利用すれば、コマンドラインからプログラムを打ち込むだけで、簡単なファイル変換コマンドが作れます。
Rubyもawkコマンドと同じようにコマンドラインから実行でき、標準入力や標準出力を利用したプログラムを作れます。そのためコマンドラインからRubyのプログラムを打ちみ、Linuxのコマンドやシェルの機能と組み合わせて使うことが可能です。
Rubyでワンライナーを作る方法
Rubyは少ない記述のプログラムが書けるスクリプト形式のプログラム言語です。そのためわずか1行のプログラムでも、意外にいろいろな処理が可能です。そしてコマンドラインからそのようなプログラムを指定できるので、ワンライナーにも組み込めます。
次からRubyでワンライナーを作る方法を紹介します。
Rubyコマンドのオプション
通常Rubyのプログラムを実行する場合、rubyコマンドの引数にソースファイルを指定します。例えば、sample.rbというソースファイルを実行する場合、次のようにコマンドラインで実行します。
ソースファイルのプログラムから実行する例
$ ruby sample.rb
しかし、Rubyのプログラムを実行する方法は、それだけではありません。引数で直接プログラムを指定することも可能です。そのような使い方をする場合は、-e オプションを使います。
引数に直接プログラムを指定する例
$ ruby -e "puts 'Ruby exec'" Ruby exec
Linuxのコマンドと組み合わせる
RubyをLinuxのターミナルから実行した結果は、何もしなければターミナルに表示されますが、その結果は標準出力に出力されています。そのため、Rubyの実行結果をLinuxのコマンドの入力に使うことが可能です。
逆にRubyは標準重力からテキストを読み込んで、それを処理するプログラムも作れます。そのためこの機能を活用することで、Linuxのコマンドを組み合わせたワンライナーにRubyのスクリプトを組み込むことも可能です。
なお、Rubyには標準入力として1行ずつ処理するための -n オプションや、awkコマンドと同じようにスペースで区切られた1行分を配列として処理できるようにする -a オプションもあります。これもうまく組み合わせて利用してください。
Rubyで短いプログラムを書くには
これまで紹介したようにRubyでは引数に直接プログラムを記述することが可能です。しかし、長いプログラムが必要な処理をワンライナーで済ませることはできません。ワンライナーにできるのは、簡単に書ける処理だけにして、複雑な処理はそれ専用のスクリプトを用意しましょう。
ただしベテランのエンジニアの中には、演算子やメソッドを駆使した短いプログラムを作成し、ワンライナーで処理してしまう方もいます。Rubyのプログラムは同じ処理でも、いろいろな書き方が可能です。
このようにRubyならもっと違った書き方ができるのでは、と思いながら学んだスキルをワンライナーに活かせます。
Rubyで作れるワンライナーの例
Rubyでもワンライナーが作れるのは解ったけど、どんなことができるのか知りたい、という方もいるでしょう。Rubyに精通したベテランエンジニアなら、こんな場面はRubyのこの処理を切り出せば使えそう、と考えて、さっと作れるかもしれません。
しかし、そのような方ばかりではありません。Rubyは使えるものの、Rubyのワンライナーを見たことがない、という方のために、次からRubyで作れるワンライナーの例を紹介します。
テキストを整形する
テキストでデータを用意したものの、それを利用するプログラムの仕様が変更されてしまい、簡単な整形が必要になった場合、Rubyのスクリプトで簡単に整形することが可能です。
この場合、シェルの機能を使い、ファイルの内容をRubyの標準入力に代入します。また、Rubyの-n、-l、-pの3つのオプションを使うことで、Linuxのコマンドのawkのように1行ずつ処理するスクリプトを作れます。
Rubyで作成したワンライナーの実行例
$ cat data1.txt aaa bbb ccc $ ruby -nle 'puts $_+ ",nil"' < data1.txt aaa,nil bbb,nil ccc,nil
正規表現でテキストを抽出する
テキストから指定した文字列を含む行を抽出する場合、Linuxではgrepコマンドを使います。しかし、grepコマンドは複雑な条件の抽出ができません。しかしRubyなら正規表現を使うことで、複雑な条件の抽出でもシンプルに記述することが可能です。
そのためRubyの正規表現を利用すれば、便利なワンライナーを作成できます。
Rubyの正規表現を利用したワンライナーの例
$ ruby -ne 'print $_ if $_ =~ /^err/' < witch.log
まとめ
これまで紹介したようにワンライナーとはLinuxのターミナルなどで、1行でさっと処理するためのコマンドの組み合わせです。そしてRubyには引数でプログラムを指定でき、また、標準入力からテキストファイルを1行単位で読み込むためのオプションもあるので、ワンライナーにRubyを組み込めます。
Rubyは1行程度の簡単なプログラムでも、演算子やメソッド、正規表現などを組み合わせることで、Linuxのコマンドだけでは実現できない、複雑な処理も可能です。ぜひ、Rubyのプログラムスキルを活かしたワンライナーをサーバーなどでの操作に利用してください。
ワンライナーで使えるRubyのオプション
-e: コマンドラインからスクリプトを指定する。
-n: while getsを適用し、senコマンドやawkコマンドのように1行ずつ処理する
-l: -nオプションで読み込んだ$_の行末の自動処理を適用する。
-a: -nオプションとともに用いて$F = $_.splitを適用する。