From: Robert Klemme Date: 2009-11-22T23:52:26+09:00 Subject: Re: How to match and count On 22.11.2009 10:12, Ruby Newbee wrote: > 2009/11/22 Phrogz : > >> # Don't read the whole file into memory, but do it one line at a time >> i = 0 >> file = File.open( "foo.txt" ) >> file.each_line do |line| >> pieces = line.split( /\s+/ ) >> i += 1 if pieces[ 3 ] =~ /something/ >> end > I like that, thank you! The code above does not close the file handle properly. Also if can be done shorter: File.foreach "file.txt" do |line| ... end You can even use Ruby like awk which seems to be rarely done - but it's possible. > awk '{if ($4~/something/) {i+=1}} END {print i}' file.txt Can be done like ruby -nae 'BEGIN {$i=0}; $i+=1 if /something/ =~ $F[3]; END {puts $i}' file.txt ruby -nae 'BEGIN {$i=0}; /something/ =~ $F[3] and $i+=1; END {puts $i}' file.txt For a script, I'd probably do something similar to what Phrogz suggested but with the difference that I'd use ARGF. That way you fetch file names from the command line and do not need to change the script if the file name changes: i = 0 ARGF.each do |line| bit = line.split(/\s+/)[3] i += 1 if /something/ =~ bit end puts i Or, do the matching in one step which seems more efficient i = 0 ARGF.each do |line| i += 1 if /^\s*(?:\S+\s+){3}something/ =~ line end puts i There are about 2,843 million other ways to do it in Ruby. Kind regards robert -- remember.guy do |as, often| as.you_can - without end http://blog.rubybestpractices.com/