Capturing STDOUT from a system call (POSIX) into an array

What’s the best way to capture STDOUT into an Array? I looked at
popen3, open4, systemu but couldn’t figure out how to do this.

In short, I want to execute a system call like “ls -l” and capture it
into an array. Of course, “ls -l” may not have proper delimiter but
assume that the delimiter is TAB or COMMA.

Thanks,

On Dec 5, 4:57 pm, Venks [email protected] wrote:

What’s the best way to capture STDOUT into an Array? I looked at
popen3, open4, systemu but couldn’t figure out how to do this.

In short, I want to execute a system call like “ls -l” and capture it
into an array. Of course, “ls -l” may not have proper delimiter but
assume that the delimiter is TAB or COMMA.

lines = ls -l.split( /\n/ )

Thanks for your quick reply. I realize that you don’t even need to use
split. What I am missing is how to create a 2 dimensional array with
each line contents in an array assuming that they are separated by a
COMMA.

Let me be more specific. Assume that we have a file under
/tmp/test.txt with the following contents.

aaa, 10, test1
bbb, 20, test2
ccc, 30, test3
ddd, 40, test4

I want to create a 2 dimensional array with each line being an array.

lines = cat /tmp/test.txt will create a single dimensional array by
default.

Thanks,

On Wed, 05 Dec 2007 18:57:51 -0500, Venks wrote:

What’s the best way to capture STDOUT into an Array? I looked at popen3,
open4, systemu but couldn’t figure out how to do this.

In short, I want to execute a system call like “ls -l” and capture it
into an array. Of course, “ls -l” may not have proper delimiter but
assume that the delimiter is TAB or COMMA.

Thanks,

You can use the IO objects returned by popen3 in any way that you’d use
a
normal file. To get an array of lines, one string per line, use
#readlines. To parse it as a CSV, for example, the csv library in ruby
should work with CSV.parse

–Ken

On 6 Dec 2007, at 09:38, Venks wrote:

ccc, 30, test3
ddd, 40, test4

I want to create a 2 dimensional array with each line being an array.

lines = cat /tmp/test.txt will create a single dimensional array
by default.

I’m not so sure about that last comment. As far as I know backticks
always return a String.

The easiest way to do what you want is just to split the String from
backticks by line and then each line by whatever delimiter you chose.
You can do this with map for instance:

[alexg@powerbook]/Users/alexg/Desktop(47): cat test.txt
aaa, 10, test1
bbb, 20, test2
ccc, 30, test3
ddd, 40, test4
[alexg@powerbook]/Users/alexg/Desktop(48): cat capture.rb
p cat #{ARGV[0]}.split(/\n/).map{|line| line.split(/, /)}
[alexg@powerbook]/Users/alexg/Desktop(49): ruby capture.rb test.txt
[[“aaa”, “10”, “test1”], [“bbb”, “20”, “test2”], [“ccc”, “30”,
“test3”], [“ddd”, “40”, “test4”]]

Alex G.

Bioinformatics Center
Kyoto University

Thanks for your reply. It works now. I was looking for the method
“map” over “split”.

Also, I tried collect! method earlier, but didn’t know how to apply
split within collect!. After seeing your example I understood the
proper syntax. I also understand that map and collect! are the same.

Actually, the output is not in a file. The output is generated by a
system call. I somehow think there is something simple in Ruby that I
can use to covert the STDOUT to a 2 dimensional array without actually
using any IO objects.

Venks wrote:

I also understand that map and collect! are the same.

map and collect are the same. As are map! and collect!.
map/collect and map!/collect! however are NOT the same.
Consider this:

arr = [1,2,3]
p arr.map {|x| x+1} # Prints [2, 3, 4]
p arr # Prints [1, 2, 3]

arr = [1,2,3]
p arr.map! {|x| x+1} # Prints [2, 3, 4]
p a # Prints [2, 3, 4] too.

HTH,
Sebastian

On Wed, 05 Dec 2007 19:38:35 -0500, Venks wrote:

ccc, 30, test3
ddd, 40, test4

I want to create a 2 dimensional array with each line being an array.

lines = cat /tmp/test.txt will create a single dimensional array by
default.

cat /tmp/test.txt will create a single string.

require ‘csv’
nested_arrays=CSV.parse(cat /tmp/test.txt)

–Ken

Thanks.

Unfortunately I learned the hard way that if I use back ticks to
execute an external command STDERR is not captured. I need to check
the status of the command before proceeding. I am looking into
“systemu” library as I may need to use threads as part of this
development process.

On Dec 6, 10:45 am, Venks [email protected] wrote:

On Wed, 05 Dec 2007 19:38:35 -0500, Venks wrote:

bbb, 20, test2
require ‘csv’
nested_arrays=CSV.parse(cat /tmp/test.txt)

–Ken


Ken (Chanoch) Bloom. PhD candidate. Linguistic Cognition Laboratory.
Department of Computer Science. Illinois Institute of Technology.
http://www.iit.edu/~kbloom1/

You can always use shell redirection to redirect stderr to stdout…

s = p ls nonexistent_dir 2>&1
p s

=> “ls: cannot access nonexistent_dir: No such file or directory\n”

Regards,
Jordan