Forum: Ruby Ruby equivalent to simple awk program

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
A87f7a014c624587fab0d3d78c5b9c18?d=identicon&s=25 Bil Kleb (Guest)
on 2006-05-04 15:24
(Received via mailing list)
Hello,

I found this awk snippet in news:comp.lang.fortran this
morning, and it made me realize that I don't use Ruby as a
*nix filter as often as I probably should because I couldn't
duplicate the capability in "about 10 seconds":

  Glen Herrmannsfeldt wrote:

  Here is an awk program that will read in a file line
  by line and write the lines out in reverse order.  It
  will allocate array elements as long as there is still
  available memory.  Variables are initialized to zero
  (or ""), even array elements.

   { array[n++]=$0;}

   END {
      while(n-->0) print array[n];
      }

  This took about 10 seconds to write and worked the
  first time.

Later,
E34b5cae57e0dd170114dba444e37852?d=identicon&s=25 Logan Capaldo (Guest)
on 2006-05-04 15:30
(Received via mailing list)
On May 4, 2006, at 9:22 AM, Bil Kleb wrote:

>  by line and write the lines out in reverse order.  It
>  This took about 10 seconds to write and worked the
>  first time.
>
> Later,
> --
> Bil
> http://fun3d.larc.nasa.gov
>

puts ARGF.readlines.reverse

At least the ruby version is more concise.
04bd97396a23bebf19887fd041e15123?d=identicon&s=25 Esteban Manchado =?iso-8859-1?Q?Vel=E1zquez?= (Guest)
on 2006-05-04 15:33
(Received via mailing list)
On Thu, May 04, 2006 at 10:22:16PM +0900, Bil Kleb wrote:
>  by line and write the lines out in reverse order.  It
>  This took about 10 seconds to write and worked the
>  first time.

    Piece of cake ;-)

    puts File.readlines('somefile').reverse

And waaaayyyy much more readable :-)

    BTW, it worked for me the _second_ time, because I initially wrote
"read_lines" instead of "readlines". I don't use that method very much
:-)
Bf6862e2a409078e13a3979c00bba1d6?d=identicon&s=25 Gregory Seidman (Guest)
on 2006-05-04 15:36
(Received via mailing list)
On Thu, May 04, 2006 at 10:22:16PM +0900, Bil Kleb wrote:
} I found this awk snippet in news:comp.lang.fortran this
} morning, and it made me realize that I don't use Ruby as a
} *nix filter as often as I probably should because I couldn't
} duplicate the capability in "about 10 seconds":
[...]
}   { array[n++]=$0;}
}
}   END {
}      while(n-->0) print array[n];
}      }
}
}  This took about 10 seconds to write and worked the
}  first time.

I have gotten pretty good with Ruby and I *can* duplicate this in about
10
seconds:

input = (ARGV.length>0) ? File.new(ARGV[0]) : $stdin
arr = []
input.each_line { |line| arr << line }
arr.reverse_each { |line| puts line }

That said, I'd be inclined to do it in awk. (Or I'd use tail -r on
systems
that support it, but that doesn't seem to include the GNU tools on
Linux.)
Ultimately, use the best tool for the job. If it's a short script in awk
and that's what comes to mind, use awk. If you find yourself jumping
through hoops working it out in awk, you'll probably have better success
in
Ruby. If you find yourself trying Perl before Ruby, however, seek
psychiatric help immediately :)

} Later,
} Bil
--Greg
E1d641bfe4071a5413bac781f06d3fd1?d=identicon&s=25 Sean O'halpin (sean)
on 2006-05-04 15:42
(Received via mailing list)
On 5/4/06, Bil Kleb <Bil.Kleb@nasa.gov> wrote:
> Hello,
>
> I found this awk snippet in news:comp.lang.fortran this
> morning, and it made me realize that I don't use Ruby as a
> *nix filter as often as I probably should because I couldn't
> duplicate the capability in "about 10 seconds":
[snip]
>   This took about 10 seconds to write and worked the
>   first time.
>
> Later,
> --
> Bil
> http://fun3d.larc.nasa.gov

puts ARGF.to_a.reverse

About 1 second to write (a bit longer to test :)

Regards,
Sean
4299e35bacef054df40583da2d51edea?d=identicon&s=25 James Gray (bbazzarrakk)
on 2006-05-04 15:49
(Received via mailing list)
On May 4, 2006, at 8:34 AM, Gregory Seidman wrote:

> I have gotten pretty good with Ruby and I *can* duplicate this in
> about 10
> seconds:
>
> input = (ARGV.length>0) ? File.new(ARGV[0]) : $stdin

If you change that to:

input = ARGF

You get the same behavior, but can accept multiple argument files on
the command-line.

> arr = []
> input.each_line { |line| arr << line }

Usually when you iterate and collect like this, it's a sign that you
really want a different method (readlines() or to_a() in this case).

James Edward Gray II
D5cf63711e59ee198fc7ec24e1a70181?d=identicon&s=25 Marco Bottaro (Guest)
on 2006-05-04 16:15
I keep finding myself iterating and collecting this way. Would you care
please to illustrate with an example?

Very much appreciated!

Cheers,

Marco

James Gray wrote:
> On May 4, 2006, at 8:34 AM, Gregory Seidman wrote:
>
>> I have gotten pretty good with Ruby and I *can* duplicate this in
>> about 10
>> seconds:
>>
>> input = (ARGV.length>0) ? File.new(ARGV[0]) : $stdin
>
> If you change that to:
>
> input = ARGF
>
> You get the same behavior, but can accept multiple argument files on
> the command-line.
>
>> arr = []
>> input.each_line { |line| arr << line }
>
> Usually when you iterate and collect like this, it's a sign that you
> really want a different method (readlines() or to_a() in this case).
>
> James Edward Gray II
E34b5cae57e0dd170114dba444e37852?d=identicon&s=25 Logan Capaldo (Guest)
on 2006-05-04 16:34
(Received via mailing list)
On May 4, 2006, at 10:16 AM, Marco Bottaro wrote:

> I keep finding myself iterating and collecting this way. Would you
> care
> please to illustrate with an example?
>
> Very much appreciated!
>
> Cheers,
>
> Marco
>

Pretty much anything with an #each has a #to_a method.
irb(main):001:0> str = "Hello\nOne\nTwo\n"
=> "Hello\nOne\nTwo\n"
irb(main):002:0> a1 = []
=> []
irb(main):003:0> str.each { |line| a1 << line }
=> "Hello\nOne\nTwo\n"
irb(main):004:0> a1
=> ["Hello\n", "One\n", "Two\n"]
irb(main):005:0> a2 = str.to_a
=> ["Hello\n", "One\n", "Two\n"]
irb(main):006:0> a2
=> ["Hello\n", "One\n", "Two\n"]

As you can see, #to_a does exactly what your code did, with a lot
less typing.
4299e35bacef054df40583da2d51edea?d=identicon&s=25 James Gray (bbazzarrakk)
on 2006-05-04 16:47
(Received via mailing list)
On May 4, 2006, at 9:16 AM, Marco Bottaro wrote:

> I keep finding myself iterating and collecting this way. Would you
> care
> please to illustrate with an example?

Well:

   arr = [ ]
   whatever.each { |e| arr << e }

Is just a long way to say:

   whatever.to_a

for any Enumerable.  Also, map() and inject() are generally other
options for avoiding these kinds of constructs.

Show us an example of where you have used it and I bet we can help
you improve it.

James Edward Gray II
02c40435f5b538c78b3590146fbd20ef?d=identicon&s=25 David Cruz (crucoba)
on 2006-05-05 00:24
(Received via mailing list)
>
> input = (ARGV.length>0) ? File.new(ARGV[0]) : $stdin
> arr = []
> input.each_line { |line| arr << line }
> arr.reverse_each { |line| puts line }
>

input.each_line { |line| arr.unshift line }

it saves an iterator
This topic is locked and can not be replied to.