QA@IT

Rubyワンライナーとシェルスクリプトの組み合わせ

2847 PV

Rubyワンライナーにより、データの加工をしています。

指定する引数により標準出力の違いが出るため、別ファイルで出力したいなーと思い、
Linuxのコマンドラインのforと試しましたが、うまくいきませんでした。

以下がプログラムのサンプルです。

for i in `seq 1 12`;do ruby -F',' -ane 'print "#{$F[0]},#{$F[1]},#{$F[3]}\n" if $F[2].strip==$i' data.csv > $i.csv;

$iの部分が上手く反映出来ません。

データのサンプル

aa,2,1,100
aa,2,2,200
aa,2,3,100
cc,2,4,100
aa,2,5,300
aa,2,6,200
bb,2,7,100
aa,2,8,100
...

Ruby内でFile呼び出せばいいじゃんって話もあると思いますが、
こんな感じで出来たら楽だなと思ってます。

回答

for i in `seq 1 12`; do ruby -F',' -ane 'print "#{$F[0]},#{$F[1]},#{$F[3]}\n" if $F[2].strip.to_i=='$i data.csv > $i.csv; done

ですかね。変更点は下記の 3 点です。

  • シングルクォート内では $i が展開されず、Ruby のグローバル変数となり、nil になってしまうため、$i をシングルクォートの外に出した。
  • $i は数値リテラルに展開され、$F[2].strip は文字列なので to_i で数値に。
  • done 追加
編集 履歴 (0)
  • なるほど、to_iすればよかったんですね。そのやり方でうまく動かずこねくりまわしてましたがタブルクォート足した時に気づけなかった orz -
  • ありがとうございます。
    想定通りのデータが抽出することが出来ました。
    シングルクォート内を脱する事で、プログラム内の数値として認識するというのは盲点でした。
    -

動きました程度のものですが・・・
自分で言うのもなんですが、エスケープがあるのですっきりしませんね。

for i in `seq 1 12`;do cmd=`printf 'print \\"#{$F[0]},#{$F[1]},#{$F[3]}\\\\n\\" if $F[2].strip==\\"%s\\"' $i`;ruby -F',' -ane "$cmd" data.csv > $i.csv; done;
編集 履歴 (0)
ウォッチ

この質問への回答やコメントをメールでお知らせします。