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
— 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
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”
endFile.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.)