rfコマンドで使用されている用語と処理の流れ
用語
rfコマンドの詳細を説明するまえに、rfコマンドで使用されている用語について解説します。
フィルタ(filter)
rfコマンドでは複数のデータ形式に対応しています。それらをRubyのオブジェクトに変換する機構が フィルタ です。フィルタはテキスト(text)、JSON、YAMLの3種類が存在します。
レコード(record)
フィルタは入力されたデータを一定のルールに従って分割します。この分割された単位をrfでは レコード と呼びます。分割するルールはフィルタによって異なります。
テキストフィルタでは改行コード(\n)で分割されます。 JSONフィルタ/YAMLフィルタではオブジェクト単位で分割されます。例えば、入力されたデータが配列なら配列の要素ごとに分割します。 Rubyのコードで表すと以下のような処理になります。
# YAMLフィルタの場合はYAML.loadになります
[JSON.load(input)].flatten(1).each do |record|
puts eval(command)
end
フィールド(field)
レコードをさらに分割したものをrfコマンドでは フィールド と呼びます。フィールドは$F変数でアクセスできます。また、_1, _2, _3...というrfコマンドで独自拡張した変数を使うと1番目のフィールド、2番目のフィールド、3番目のフィールド…へアクセスすることができます。 フィールドへの分割は自動で行われますが、$_または_ 変数を使うとフィールドに分割されていないレコードにアクセスできます。
フィールドの分割ルールはフィルタによって異なります。テキストフィルタの場合は空白文字で区切られます。String#splitを引数なしで呼び出した時と同じ挙動です。-Fオプションを指定すると区切り文字を変更できます。区切り文字は正規表現を使うことも可能です。JSONフィルタ/YAMLフィルタは、レコードが配列だった場合にのみフィールドに分割します。 それ以外のデータ型だった場合は_1にのみ格納され、_2以降はnilになります。
コマンド(command)
フィルタ処理を記述するRubyのコードのことを コマンド と呼びます。コマンドは引数で指定するか、もしくは、スクリプトファイルとして読み込むこともできます。
フォーマッタ(formatter)
rfコマンドではコマンドを実行し評価した結果を出力します。出力する際に適切な形式に変換する機構を フォーマッタ と呼びます。フォーマッタはフィルタによって自動で選択されます。たとえば、JSONフィルタを選択している場合は、JSONフォーマッタが自動で選択されます。後述しますが、to_yamlなどのメソッドを使うことで、任意のフォーマットで出力することが可能です。
処理の流れ
rfコマンドの処理の流れを解説します。
まず、データの入力を行います。これはコマンドラインで指定されたファイルまたは標準入力から行います。
次に、フィルタを通して入力したデータをRubyのオブジェクトに変換しレコード単位に分割します。
分割したレコードに対してコマンドを実行し、評価した結果を受け取ります。
評価結果をフォーマッタを通して出力します。
Discussion