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

Hi I have a question to ask regarding printing array outside of the loop. let say i have multiple files such as F1 , F2 , F3 etc in each files , i have a similar PATTERN such as below:
See asfdfdfd #ERRORS pattern to grep pattern to grep CELLS cellpattern abcdef gfghtht
i would like to grep all the lines between #ERRROR and cellpattern.(including both #ERROR and cellpattern) next, i would like to print out each pattern outside of my foreach loop(used to loop all files) so it will becomes like this:
output: bla bla bla ( different result from other code) bla bla bla ( different result from other code) bla bla bla ( different result from other code) #ERRORS <------------ from file F1 pattern to grep pattern to grep CELLS cellpattern #ERRORS <------------ from file F2 pattern to grep pattern to grep CELLS cellpattern the way my code is written print them out as they parse the line which + is not what i want . example of my current result bla bla bla #ERRORS <------------ from file F1 pattern to grep pattern to grep CELLS cellpattern bla bla bla bla #ERRORS <------------ from file F2 pattern to grep pattern to grep CELLS cellpattern

Replies are listed 'Best First'.
Re: print content of array individually after parsing multiple input files
by Anonymous Monk on Dec 10, 2014 at 02:38 UTC
      hi monk, okok here is the code i wrote. i didnt put here at first because i just want to know the algorithm on the flow . btw, my code is pretty crude so hope do not mind on it.
      if (exists $args{dir}) { if(-e $args{dir}) { $directory =$args{dir}; { print "Path: $directory\n\n"; } } else { print "-E- the dir does not exist $args{dir}\n"; exit; } } opendir (DIR , "$directory") || die "Cannot open $directory\n"; chdir($directory); $cmd = "ls -t"; chomp ( @files = grep { /log.sum/} `$cmd` ); #print "@files\n"; $flag_flow = 0 ; $flag_tool = 0 ; print "Script version : v1\n\n"; print "Timestamp Cell Status\t Flow\t\t\t + # Errors\t # Warnings\n"; print "========= ====== ====== ====== + ========= ==========\n"; foreach (@files) { if(/(\S+)\.(\S+).iss.log.sum/) { $cellname = $1; } @full = "$directory/"."$_"; foreach my $files (@full) { open INFILE , "<$files" ; open OUTPUT , ">>result.txt" ; my @lines = <INFILE>; my $timestamp = ctime(stat($files)->mtime); my $time = substr($timestamp , 4 , -8); foreach (@lines) { if (/Status\s+Flow/) { $flag_flow = 1; } if($flag_flow) { next if (/====/); if (/^(clean|DIRTY)\s+(\S+)\s+(\S+)\s+(\S+)/) { $data{$a}{Status} = $1; $data{$a}{Flow} = $2; $data{$a}{Errors} = $3; $data{$a}{Warnings} = $4; push @array , $_; #print "$time $cellname $_"; foreach $array (keys %data) { #@summary ="$time\t $cellname $data{$array}{Status} +\t $data{$array}{Flow}\t $data{$array}{Errors}\t\t $data{ +$array}{Warnings}\n"; print "$time\t $cellname $data{$array}{Status}\t $d +ata{$array}{Flow}\t $data{$array}{Errors}\t\t $data{$arra +y}{Warnings}\n"; } } @array = (); } if(/^\s*$/) { $flag_flow = 0 ; } if(/See\s+\$PDSLOGS\/(\S+)\.(\S+)\.icv/) { $error_cellname = $1; $error_flow = $2; #print"$_\n"; #push @match , "cell is $error_cellname , flow is $error_ +flow\n" ; print "CELL = $error_cellname , FLOW = $error_flow\n"; print "===========================================\n"; $error_count = 1; } elsif(/PLAYERR Files Created/) { $error_count = 0; } elsif($error_count) { #push (@err , $_); print "$_"; } } close INFILE ; } } exit;
      as you can see , after i print out $error_cellname or $error_flow , all the element will be treated as single element (due to the way i code my main code). i would like to print out the element individually so that i can produce the output i desired(as in my first post)

        I'm sorry to say there are a lot of issues with your code that make it really hard to read and debug. If you want help with the code, the first thing you need to do is Use strict and warnings, and second you should run it through perltidy and get rid of all those extra blank lines. You've got some unused handles (e.g. DIR and OUTPUT) and you'll need to decide on the variables' scopes. Plus a few more things, like missing error handling (... or die) on opens, ...

        I'm still a little unclear on the problem statement, but I can give a general answer to what was posted below:

        use warnings; use strict; my @errors; for my $input (1..3) { # main loop, just a demo # do something with $input here print "pattern$input\n"; if ($input%2) { # whatever your error condition is push @errors, "error$input"; } } print "\n#errors\n"; # main loop over, now output @errors for my $error (@errors) { print "$error\n"; } print "cellpattern\n";

        As you operate over the input to produce the output, you accumulate the errors in @errors, and then, after the main loop, you loop over @errors to output the contents of that array. The output of the above snippet is:

        pattern1 pattern2 pattern3 #errors error1 error3 cellpattern
Re: print content of array individually after parsing multiple input files
by Laurent_R (Canon) on Dec 10, 2014 at 07:31 UTC
    Sorry, I don't really understand what you are looking for. The only difference I can see between your desired and your actual output is the "bla bla" line, which seems to be coming out of nowhere. Is there anything more to be noticed?
      hi Laurent ok , let me further clarify want i want to produce as my output is display <pattern*> top of file and <#errors to cellpattern> bottom of file. right now whenever a file has #errors, it will parse and display together with pattern* .this is because i can't print them out of the main code.
      desired output pattern1 pattern2 pattern3 #errors . .. cellpattern
      current output i get pattern1 #errors . .. cellpattern pattern2 #errors . .. cellpattern pattern3 #errors . .. cellpattern
Re: print content of array individually after parsing multiple input files
by RonW (Parson) on Dec 10, 2014 at 22:02 UTC

    Disclaimer: Not tested.

    Maybe something like this:

    my $getPatterns; while (<>) { if (/^#ERRORS/ .. /^CELLS/) { push(@errors, $_); $getPatterns = 1; next; } elsif (defined $getPatterns) { push(@errors, $_); $getPatterns = undef if (/^\s*$/); next; } ...; # other processing } print "Errors:\n"; for (@errors) { print " $_"; }

    Update: I think this could be written as:

    Update 2; No, it won't work.

    while (<>) { if (/^#ERRORS/ .. /^CELLS/) { push(@errors, $_); } elsif (/^CELLS/ .. /^\s*$/) { push(@errors, $_); } else { ...; # other processing } } print "Errors:\n"; for (@errors) { print " $_"; }