kirk123 has asked for the wisdom of the Perl Monks concerning the following question:

Hi,

I am getting different result from accessing an array as oppose to reading from a file.

Earlier I was executing a unix command and reading the result like this:

system("lpstat -v -d -p -l -D >junk.txt"); open RI,"<junk.txt" || die "Can't open junk.txt for reading:$!\n"; my $data = do { local $/; <RI> }; # or however you load it. my( %device, %system ); for ( split /\n(?=\S)/, $data ) { if( /^device for (.*?):.*?\1$/ ) { $device{$1} = $1; } elsif ( /^system for (.*?): (\S+)/ ) { $system{$1} = $2; }
------
--

But now I want to avoid opening and reading from a file so I use an array instead:

my @output =`lpstat -o -v -d -p -l -D`;. my( %device, %system ); foreach my $line (@output) { chomp $line; for ( split /\n(?=\S)/, $line ) { if (/^system default/) { @test = split(/ /); chomp($test[3]); print "$test[3]|\n"; } if( /^device for (.*?):.*?\1$/ ) { $device{$1} = $1; } elsif ( /^system for (.*?): (\S+)/ ) { $system{$1} = $2; }

----
--
But by using an array I am getting a different answer than what I am getting by using a file.

How can I change my "array" code so that it works just like reading a file.

--thanks kirk123

20030218 Edit by Corion : Added formatting

Replies are listed 'Best First'.
Re: How is outputting to an array different from outputting to a file
by mojotoad (Monsignor) on Feb 17, 2003 at 01:02 UTC
    You aren't really treating them the same by localizing the input record separator:

    my $data = do { local $/; <RI> }; # or however you load it.

    Instead try this:

    @data = <RI>; chomp(@data);

    or

    while ($line = <RI>) { chomp $line; ... }

    Then cycle through the data list. This is what you do in your array example.

    I suppose that answer is a bit backwards, however. Once you get the data in list format, you no longer need the split that you were using due to having overridden the input record separator:

    for ( split /\n(?=\S)/, $line )

    Instead just use:

    for my $line (@lines) {
    Matt
Re: How is outputting to an array different from outputting to a file
by blokhead (Monsignor) on Feb 17, 2003 at 01:04 UTC
    Your code definitely does not compile so it's not clear what you've really tried. Do you intend to have the second for loop inside the foreach loop? Your indentation suggests otherwise. You don't have a closing brace there (among other syntax errors).

    The short and long of it: replace this from the first snippet:

    system("lpstat -v -d -p -l -D >junk.txt"); open RI,"<junk.txt" || die "Can't open junk.txt for reading:$!\n"; my $data = do { local $/; <RI> }; # or however you load it.
    With this:    my $data = `lpstat -v -d -p -l -D`; An array isn't really necessary. In fact, in your example you were putting the entire results of the command into only the first element of your array.

    blokhead

Re: How is outputting to an array different from outputting to a file
by graff (Chancellor) on Feb 17, 2003 at 02:10 UTC
    In order to make the second case work like the first one, you need to have the back-tick command assign its value to a scalar, rather than to an array:
    my $data =`lpstat -o -v -d -p -l -D`;.
    In other words, if your first example (reading from the file) actually works, then all you need to do is replace these lines:
    system("lpstat -v -d -p -l -D >junk.txt"); open RI,"<junk.txt" || die "Can't open junk.txt for reading:$!\n"; my $data = do { local $/; <RI> };
    with the one back-tick line I showed above, and everything else should stay the same and still work.
Re: How is outputting to an array different from outputting to a file
by dws (Chancellor) on Feb 17, 2003 at 01:32 UTC
    I am getting different result from accessing an array as oppose to reading from a file.

    Observation: You're not chomp'ing in the first case, and over-chomp'ing in the second.

Re: How is outputting to an array different from outputting to a file
by manux (Initiate) on Feb 18, 2003 at 14:08 UTC

    you can also do:

    open ( RI,"lpstat -v -d -p -l -D |") || die "Can't run
    lpstat:$!\n";

    my $data = do { local $/; <RI> }; # or however you load it.


    (but in this case is better $data=`lpstat -v -d -p -l -D`...unless you modify the script and you work on lpstat output line by line)