一般的にシェルからRubyなどを呼ぶ場合、短ければワンライナー、長ければ別ファイルにすれば良い。
しかし、ワンライナーには長ずぎる、ファイルにするには少々短いというRubyやPythonなどのコードもある。そういうコードをシェルスクリプトに埋め込む方法を記す。
その方法は、$()
の中でヒアドキュメントをcatし、変数に入れて-eオプションでワンライナーと同じように実行するというもの。
#!/bin/bash ruby_script=$(cat <<- 'EOF' lines = $stdin.readlines width = (lines.map{ |line| line.split.first.size }.max / 8 + 1) * 8 lines.map(&:split).each { |a, b| puts "#{a.ljust(width)}#{b}" } EOF ) ruby -e "${ruby_script}" < data.txt
変数の代わりにプロセス置換を使ってファイル扱いでrubyに渡すこともできる
#!/bin/bash ruby <(cat <<- 'EOF' lines = ARGF.readlines width = (lines.map{ |line| line.split.first.size }.max / 8 + 1) * 8 lines.map(&:split).each { |a, b| puts "#{a.ljust(width)}#{b}" } EOF ) < data.txt
デバッグが難しくなるのであまり長いコードを埋め込むのはお勧めしない。多くても5行程度に収めたい
ちなみに例示したRubyスクリプトはcatするとこんなふうに表示されるタブ区切りのファイルを
1234 abcdefg 123456789 abcdefg 1234567 abcdefg 12345678901234 abcdefg
以下のように整形してターミナルに出力するというもの
1234 abcdefg 123456789 abcdefg 1234567 abcdefg 12345678901234 abcdefg
タブ幅を調整するだけならtabsというコマンドでもできる。
tabs "-$(ruby -e 'puts (ARGF.map{ |line| line.split.first.size }.max / 8 + 1) * 8' < data.txt)" cat data.txt