Ruby translation for UNIX scripting command

Quick (and slightly embarassing) newbie question for the Ruby experts. I’m trying to learn Ruby, and move away from antediluvian UNIX scripting.How do I make a sequence of pattern matching lines in a file, then extract a particular field from the line? For example, in UNIX talk if I were interested in finding all lines with a particular match pattern “test”, and printing the fourth field, I’d do a grep plus awk command such as:grep “test” file_name | awk ’ { print $4 } ’ >> output_fileHowever, in my Ruby books, I don’t see any discussion about the function equivalent of printing a field of the type “$4” (i.e. fourth field). I can get the lines out of the search file, but I’m not quite sure how to determine fields.Thanks.TPL

···

Join Excite! - http://www.excite.com
The most personalized portal on the Web!

— Thomas Luedeke tluedeke@excite.com wrote:

pattern “test”, and printing the fourth field, I’d do a grep plus awk
command such as:grep “test” file_name | awk ’ { print $4 } ’ >>
output_fileHowever, in my Ruby books, I don’t see any discussion about

You win the UuoGA (Useless Use of Grep Award). Why not let awk to the
pattern matching?

awk ‘/test/ {print $4}’ < file_name >> ./some_other_file

– Thomas Adam

···

=====
“The Linux Weekend Mechanic” – http://linuxgazette.net
“TAG Editor” – http://linuxgazette.net

“ We’ll just save up your sins, Thomas, and punish
you for all of them at once when you get better. The
experience will probably kill you. :)”

– Benjamin A. Okopnik (Linux Gazette Technical Editor)


Yahoo! Messenger - Communicate instantly…“Ping”
your friends today! Download Messenger Now
http://uk.messenger.yahoo.com/download/index.html

I’d say:

open(‘filename’).grep(/pattern/).split[4]

···

il Sat, 6 Mar 2004 03:15:08 +0900, “Thomas Luedeke” tluedeke@excite.com ha scritto::

“Thomas Luedeke” tluedeke@excite.com schrieb im Newsbeitrag
news:20040305181503.955C3B6CC@xprdmailfe14.nwk.excite.com

Quick (and slightly embarassing) newbie question for the Ruby experts. I’m
trying to learn Ruby, and move away from antediluvian UNIX scripting.How do
I make a sequence of pattern matching lines in a file, then extract a
particular field from the line? For example, in UNIX talk if I were
interested in finding all lines with a particular match pattern “test”, and
printing the fourth field, I’d do a grep plus awk command such as:grep
“test” file_name | awk ’ { print $4 } ’ >> output_fileHowever, in my
Ruby books, I don’t see any discussion about the function equivalent of
printing a field of the type “$4” (i.e. fourth field). I can get the lines
out of the search file, but I’m not quite sure how to determine
fields.Thanks.TPL

$> ruby -a -n -e ‘puts $F[3] if /test/’ test-file.txt

If you need to split with another pattern, do

$> ruby -a ‘-F\s+’ -n -e ‘puts $F[3] if /test/’ test-file.txt

Regards

robert

except that element number four is the fifth element. no, not the movie
:wink:

open(‘filename’).grep(/pattern/).split[3]

Also, unless I misunderstand, I think there may be many many lines; and
grep returns an array, which can’t be split.

if you want to create a filter script, that filters stdin to stdout:

STDIN.read.grep(/pattern/).each{|line| puts line.split[3]}

If, on the other hand, you want a script that you can call like this:

% myscript input_file output_file

then you will be needing to read up a little more in ruby, I think. But
here’s some code for an example:

filtered_data = File.open(“input_file”) do |file|
file.read.grep(/pattern/).map{|line| line.split[3]}.join “\n”
end

File.open(“output_file”) do |file|
file.write filtered_data
end

–Mark

···

On Mar 5, 2004, at 10:24 AM, gabriele renzi wrote:

il Sat, 6 Mar 2004 03:15:08 +0900, “Thomas Luedeke” > tluedeke@excite.com ha scritto::

I’d say:

open(‘filename’).grep(/pattern/).split[4]

Mark Hubbart wrote:

If, on the other hand, you want a script that you can call like this:

% myscript input_file output_file

then you will be needing to read up a little more in ruby, I think. But
here’s some code for an example:

filtered_data = File.open(“input_file”) do |file|
file.read.grep(/pattern/).map{|line| line.split[3]}.join “\n”
end

File.open(“output_file”) do |file|
file.write filtered_data
end

This can be simplified to:

filtered_data = File.read(“input_file”).grep(/pattern/)
.map { |line| line.split[3] }

File.open(“output_file”) do |file|
file.puts filtered_data
end

It might however be better to do all this in one pass over the data
without using any buffers – I’d do that like this:

filtered_data = Array.new
File.foreach(“input_file”) do |line|
if md = /^(#\w+) ([\d:]+) (<\w+>) (.*?)$/.match(line)
channel, time, nick, text = md.captures
filtered_data << text
end
end

File.open(“output_file”) do |file|
file.puts filtered_data
end

This implementation does also allow one to keep a part of the matching
line not surrounded by whitespace. (Which means that one could also use
it on CSV data or similar input.)