nims
nims

Reputation: 103

while loop to execute a command multiple times and store the output in a different variable each time

I want to execute a command thrice, and store the output of the command execution in a different variable each time. The below code is to store it in the same variable each time. How do i store in different variable ?

   int $i=0;
   while ( $i< 3 ) {
    $a = ( " command gets executed her " );
    $i = $i+1 ;
   } 

I want the output to be stored in three different variables say $a $ b and $ c.

Upvotes: 1

Views: 514

Answers (1)

zdim
zdim

Reputation: 66883

You can store output in an array

my @output;

for (1..3) {
   my $cmd = '...';
   push @output, scalar qx($cmd);
}

Now elements of @output have the output of consecutive command runs.

Note that qx (backticks) can return either a string with all lines of output from a command, or a list with lines of the output being the elements, depending on the context in which it is called.

my @out = qx(ls -l .);  # @out elements have lines from output
my $out = qx(ls -l .);  # all lines from output are in string $out

Since push takes a list to push onto an array, the list context is imposed and (without the scalar) qx would return a list of lines from a command (when the output has more than one line). Thus each line would be added as a separate element to @output. But scalar forces the scalar context and then the whole output of each command goes into a string, which is added as a single element. So we get an array with three elements, each being a (potentially multi-line) string. Thanks to ThisSuitIsBlackNot for a comment.

How you are getting the output of a command is a different question. Here I've assumed that the "command" implies an external command which prints to its STDOUT, and I omit error checking. It is better to run qx and capture its output, check for errors, and only then put output on the array.


There is a specific requirement to assign to separate variables. One way

my ($out1, $out2, $out3);

for ($out1, $out2, $out3) {
    my $cmd = '...';
    $_ = qx($cmd);
}

Here you have to explicitly list variable names, both to declare them and to loop over them. That doesn't make for very good code, since you have to list all variables, it is harder to keep track of things, and any changes that come have to be applied to multiple places.

If you are thinking about constructing variable names on the fly, to avoid dealing with lists of variables, that means dealing with symbolic references -- and you don't want to do that. A lot has been said against it over time and it is a very clearly discouraged practice. See, for example, this post. For one thing, use strict doesn't allow it.

If you insist on having names, you could use a hash with key names built at runtime

my %out;

for (1..3) {
    my $cmd = '...';
    my $key = 'o' . $_;  # name keys as 'o1', 'o2', etc
    $out{$key} = qx($cmd);
}

for (sort keys %out) {
    print "$_ => $out{$_}\n";
}

Note that you again have to make up those specific key names and keep track of them.

I'd advise to use an array, if at all possible. When you process that you can always assign to a named variable as you loop over it, for example. Or, better, to reconsider the design that leads to this need.

Upvotes: 5

Related Questions