-1

Want to run Ruby like this

cat *.txt |my_print_last_line.rb

And have the last line of each file printed (might do something interesting if I could first print)

The ARGF class seems promising to solve it. Tried this:

ARGF.each do |line|
  last_line_of_file = line[last] 
  puts last_line_of_file
end

However ARGF.each seems to be one long string of all files concatenated rather than the individual files.

mu is too short
  • 426,620
  • 70
  • 833
  • 800
Mikef
  • 1,572
  • 2
  • 10
  • 21

1 Answers1

1

This has to do with how cat handles multiple files. It just concatenates them:

$ echo 'foo' > foo
$ echo 'bar' > bar
$ cat *
foo
bar

This means that after issuing the cat command there's no way of telling where the individual files started and ended. If you would just invoke your script as ruby my_print_last_line.rb *.txt you would still have the same problem because using ARGF will also simply concatenate all files.

As an alternative, you could take the filenames as parameters to the ruby script to open and read the files directly in ruby:

ARGV.each do |file|
  puts IO.readlines(file).last
end

Then invoke your script like this:

$ ruby my_print_last_line.rb *.txt

If you are reading really large files, you may gain a significant performance benefit by using a seek based approach, as described by @DonaldScottWilde in this answer to a similar question.

Community
  • 1
  • 1
Patrick Oscity
  • 53,604
  • 17
  • 144
  • 168
  • How about When it it needs to be run recursively : for example find . -name "*.txt" |my_print_last_line.rb – Mikef Jul 28 '13 at 00:22
  • That's not [recursive](http://en.wikipedia.org/wiki/Recursion_(computer_science)). Please be more specific where the problem is, should work as it is! – Patrick Oscity Jul 28 '13 at 00:28
  • Running the Ruby on *.txt only expands files in the cwd, what if I want a to run in on all files in the tree as would be produced by >find . -name "*.txt" – Mikef Jul 28 '13 at 00:29
  • You can run the script via `find` using the `-exec` flag: `find . -name "*.txt" -exec ruby my_print_last_line.rb {} \;` – Patrick Oscity Jul 28 '13 at 00:31
  • Running under windows from a dos prompt. Get the following errors. /test.rb: line 2: syntax error near unexpected token `(' test.rb: line 2: ` puts IO.readlines(file).last' Ran it like this: find . -name "*.txt" -exec test.rb {} ; The test.rb is the 3 lines of code you provided. BTW running Ruby 1.93 – Mikef Jul 28 '13 at 02:08
  • Sorry, i have no clue about windows to be honest. – Patrick Oscity Jul 28 '13 at 07:47