ファイルfoo.txtのn行目からm行目までを表示するワンライナーで、
$ cat foo.txt | ruby -ne 'print if n..m'
という書き方をよく目にします。
このワンライナー中でRubyの実行スクリプトの部分は、
省略せずに書くと、どのようになるのでしょうか?
特に範囲オブジェクトが、何に作用しているのかがわかりません。
ファイルfoo.txtのなかで正規表現にマッチする行を表示するワンライナー
$ cat foo.txt | ruby -ne 'print if /bar/'
は、
while gets()
print $_ if $_ =~ /bar/
end
だと思うのですが、
できればこのような形で示していただけると助かります。
初歩的な質問で申し訳ありませんが、よろしくお願いします。
ん、実行しても素通りするだけですが?
$ wc -l ~/.emacs 200 /m/home/rubikitch/.emacs $ cat ~/.emacs | ruby -ne 'print if 2..4' | wc -l 200
> $ cat foo.txt | ruby -ne 'print if n..m'
Perlだとそのまんまでいけますけど、
Rubyの場合、確かにそのままじゃいかんすねぇ(いけるバージョンあるのかなぁ)。
komamitsu@onion:~/caml$ wc -l tree.ml
13 tree.ml
komamitsu@onion:~/caml$ cat tree.ml | perl -ne 'print if 2..4' | wc -l
3
komamitsu@onion:~/caml$ cat tree.ml | ruby -ne 'print if 2..4' | wc -l
13
特殊変数 $. の値を比較してあげればいいから、適当にこう?
komamitsu@onion:~/caml$ cat tree.ml | ruby -ne 'print if (2..4).include? $.' | wc -l
3
ちなみに、Perlのほうは、
暗黙的に $. との比較を行っている、みたいな。
何か抜けてませんか?
こんなのならわかりますが。
$ cat foo.txt | ruby -ne 'print if ($.==2)..($.==4)' line 2 line 3 line 4
条件式として範囲式が用いられた場合には、状態を持つ sed や awk 由来の特殊な条件式として振る舞います。
「..」の場合:
- 初期状態では式1だけを評価し、式1が真を返すまでは false を返します。
- 式1が真を返すと true を返します。式2が真なら初期状態に戻ります。
- この後は式2だけを評価し、式2が真を返すまで true を返します。
- 式2が真を返すと true を返したあと、初期状態に戻ります。
Rubyのバージョンが結構古かった(1.8.1)のですが、
そのへんも影響しているのでしょうか。
手元の環境では、以下のようにできました。
[kanouk@rhel ~]$ ruby -v
ruby 1.8.1 (2003-12-25) [i386-linux-gnu]
[kanouk@rhel ~]$ cat .cshrc | wc -l
32
[kanouk@rhel ~]$ cat .cshrc | ruby -ne 'print if 2..5' | wc -l
4
違う環境(1.8.6)で試してみたら、
おっしゃる通り素通りしました。