Gshaw
Gshaw

Reputation: 47

Can't figure out this simple perl error?

For an array i am checkinit setting some condition in foreach loop. only if it is true, i want to assign $_ to another array.. but the simple @stale = $_; is not appending to it.. neither is push or any other function for that matter..

Any idea what can be done to resolve this?

Edit: Code from comment by OP

# To give a generic ORACLE_HOME and HOSTNAME path for all the instances.
#
#using shell ENV variable in perl
my $home  = $ENV{'ORACLE_HOME'};
#
#concatenating the paths
my $subdir = "/ccr/hosts/";
my $subdir1 = $home.$subdir;
my $host = "`hostname`/state/review";
my $subdir2 = $subdir1.$host;
#
#assigning each row of command output to an array
@infile = `ls -ltr $subdir2`;
#
#printing each value of the array i.e. file details
foreach (@infile) {
        chop($_);
        $m_age = -M $_;
        if (($stale = `date` - $m_age) < 1.0) {
#
#
#change/correct this line :(
#
#
                printf "\nFile %s was last modified 24hrs back. stale collections. \n" , $_ , $m_age ,$stale;
                push @stale_files , $_;
        }
        else {
        @not_stale_files = $_[$q++];
        }
        $count++;
}
print "\n for stale:\n";
foreach $i (@stale_files) {
print "$stale_files[$i]\n";
}

Also, each time the loop executes, $_ value is expected to be appended to @stale. But only the last value of $_ (obtained during the last time loop runs) is getting assigned to @stale.

Upvotes: 0

Views: 119

Answers (2)

Matteo
Matteo

Reputation: 14930

Ok let's review the edited code

Please use

use warnings;
use strict;

in your code: it will help you detect errors

# To give a generic ORACLE_HOME and HOSTNAME path for all the instances.
#
#using shell ENV variable in perl
my $home  = $ENV{'ORACLE_HOME'};
#
#concatenating the paths
my $subdir = "/ccr/hosts/";
my $subdir1 = $home.$subdir;

you don't need to have complicated constructs

my $subdir1 = $ENV{'ORACLE_HOME} . '/ccr/hosts';

is enough

The next line will not work: back ticks will not be expanded in a " quoted string

my $host = "`hostname`/state/review";
my $host = `hostname` . '/state/review';

my $subdir2 = $subdir1.$host;
#
#assigning each row of command output to an array
@infile = `ls -ltr $subdir2`;

Here @infile will contain more than the files. Each element will have the output of ls -ltr. Something like

total 16
-rw-r--r--  1 corti  corti   94 Sep 14 11:40 test.pl~
-rw-r--r--  1 corti  corti  979 Sep 14 11:49 test.pl

#
#printing each value of the array i.e. file details
foreach (@infile) {
    chop($_);

here you are doing something like -M -rw-r--r-- 1 corti corti 94 Sep 14 11:40 test.pl~.

    $m_age = -M $_;
    if (($stale = `date` - $m_age) < 1.0) {
       #
       #
       #change/correct this line :(
       #
       #
       printf "\nFile %s was last modified 24hrs back. stale collections. \n" , $_ , $m_age ,$stale;

It is correct. The problem is in the content of $_

            push @stale_files , $_;
    }
    else {

$_ is an element of @infile. What do you want to achieve whith $_[]? What is $q?

    @not_stale_files = $_[$q++];
    }

Also $count is never initialized

    $count++;
}
print "\n for stale:\n";
foreach $i (@stale_files) {
  print "$stale_files[$i]\n"; 
}

Upvotes: 1

Dave Sherohman
Dave Sherohman

Reputation: 46187

Using "push @stale, $_;" (which adds to the end of the array) instead of "@stale = $_;" (which completely replaces the existing contents of the array) should work in this case.

Edit: Proof that push does what is asked.

Code:

#!/usr/bin/env perl

use strict;
use warnings;

my @numbers = (1, 8, 3, 5, 2, 8, 9, 0);
my @stale;

for (@numbers) {
    if ($_ < 5) {
        printf "\nNumber %s is less than five.\n", $_;
        push @stale, $_;
    }   
}

print join ", ", @stale;
print "\n";

Output:

$ ./add_to_array.pl 

Number 1 is less than five.

Number 3 is less than five.

Number 2 is less than five.

Number 0 is less than five.
1, 3, 2, 0
$

Upvotes: 0

Related Questions