rayv has asked for the wisdom of the Perl Monks concerning the following question:
I am attempting to read a directory to get all files in the directory, pass these file names into a foreach loop. These files are all monthly PS Accounting Report Files, which I need to parse in the foreach loop to determine those that match a particular month. The PS Account Files have the following format:
Jun 1 03:20 2007 MONTHLY USAGE FOR 05/2007 FOR xsd00544 Page 1 LOGIN CPU (MINS) KCORE-MINS CONNECT (MINS) DISK + # OF # OF # DISK FEE UID NAME PRIME NPRIME PRIME NPRIME PRIME NPRIME + BLOCKS PROCS SESS SAMPLES 0 TOTAL 11997 26981 799331072 1899742080 13264 20 +500 0 32403945 226 0 0 0 root 1089 2594 12452976 29521392 0 0 0 11 +588066 0 0 0 1 daemon 0 0 174 423 0 0 0 3293 0 0 + 0 3 sys 1 4 1805 5657 0 0 0 9387 0 0 + 0 4 adm 1 52 546 48639 0 0 0 37050 0 0 + 0 71 lp 0 0 0 12 0 0 0 20 0 0 0 103 ctsccw1 0 0 75 22 35 12 0 164 6 0 + 0 108 scoilg1 0 0 14 0 1720 4070 0 26 6 + 0 0 116 sdbaa12 0 0 140 24 475 838 0 212 12 + 0 0 117 dptid01 0 0 0 0 0 21 0 0 29 0 +0 118 sdbast1 0 0 195 21 0 0 0 94 0 0 + 0 121 sdbaa01 0 0 0 0 5 0 0 0 1 0 0 170 cmredm1 0 0 0 2 0 463 0 3 2 0 +0 223 pimdp01 0 4 152 9135 0 0 0 1780 0 + 0 0 226 sdbasc2 0 0 21 0 140 0 0 39 2 0 + 0 228 mqm 5 19 15007 46540 0 0 0 150133 0 + 0 0 269 pirdp01 3 1 15850 2602 0 0 0 1311 0 + 0 0 284 pptip01 0 16 0 120016 0 0 0 3175 0 + 0 0 317 pomgp01 19 37 78967 285738 0 0 0 178868 + 0 0 0 335 ammdcc1 0 0 7 0 122 0 0 29 1 0 + 0 340 sdbsby1 0 0 1 3 0 109 0 1 1 0 +0 359 pmfwp01 0 0 0 1 0 0 0 1 0 0 0 404 bmw 0 0 5 0 0 0 0 14 0 0 0 405 ccsssl1 0 0 0 3 0 7 0 8 1 0 0 406 scspfw1 0 0 14 0 776 0 0 18 3 0 + 0 409 ccssll1 0 0 0 4 0 132 0 12 1 0 + 0 410 ccsslv1 0 0 18 0 0 0 0 22 0 0 +0 594 pipmp01 591 1151 20229524 42349476 0 0 0 + 6576051 0 0 0 605 pbmwp01 0 3 0 99267 0 0 0 495 0 0 + 0 643 ccssat1 0 0 0 14 0 724 0 20 4 0 + 0 645 ccssjt1 0 0 0 1 0 25 0 9 1 0 0 790 cmrejc1 0 0 4 13 20 738 0 31 9 0 + 0 799 cdigjc1 0 0 15 0 1424 0 0 20 4 0 + 0 817 domsd01 0 0 71 0 24 0 0 20 9 0 + 0 819 cmresp2 0 0 6 29 723 2506 0 47 11 + 0 0 824 cmrehc1 0 0 12 16 266 669 0 42 6 +0 0 942 sdbamg1 0 0 28 0 243 0 0 69 3 0 + 0 958 maestro 335 685 1506022 3072424 0 0 0 2 +066 0 0 0 1001 ndmuser 78 279 242614 918368 0 0 0 707 +430 0 0 0 1003 amssmt2 0 0 18 0 86 0 0 68 2 0 + 0 1005 amsspw1 0 0 0 0 18 0 0 0 1 0 +0 1057 cmrerb1 0 0 5 4 577 40 0 16 5 0 + 0 1128 ccssrs1 0 0 0 2 195 369 0 3 2 0 + 0 1130 ccsswc1 0 0 0 10 0 463 0 12 5 0 + 0 1157 sybprd01 0 0 0 3 0 0 0 3 0 0 +0 1164 s2p1 0 0 6 0 25 0 0 5 1 0 0 1221 scspba1 0 0 5 6 4 12 0 19 2 0 + 0 1280 sybsrd0k 17 63 5824025 13749965 0 0 0 +14779 0 0 0 1356 sdbasn1 0 0 20 4 256 834 0 28 3 +0 0 1360 dimcd01 0 0 20 7 132 8 0 30 4 0 + 0 1451 sybprd0l 1482 3844 12557 2853173 0 0 0 + 103885 0 0 0 1477 sdsmfl1 0 0 4 0 128 0 0 10 1 0 + 0 1496 f2pa 256 580 4356176 10327754 0 0 0 75 + 0 0 0 1508 pdb2admn 0 1 0 5111 0 0 0 1275 0 + 0 0 Jun 1 03:20 2007 MONTHLY USAGE FOR 05/2007 FOR xsd00544 Page 2 1597 scoiyk1 0 0 6 0 15 0 0 8 1 0 +0 1608 ccssro1 0 0 4 0 179 0 0 10 1 0 + 0 2014 ccssjj1 0 0 0 3 0 2 0 10 1 0 +0 2132 s2pe 3277 5178 349899264 649494912 0 0 0 + 6362691 0 0 0 2136 s2pi 1 2 71260 171081 0 0 0 5587 0 + 0 0 2614 s2pv 0 1 10975 30646 0 0 0 1156 0 + 0 0 3916 spmdjg1 0 0 0 474 0 0 0 10 0 0 + 0 4529 sdsmmm1 0 0 20 0 1 0 0 69 5 0 + 0 4774 dctid01 1 0 366960 24 3720 3648 0 1163 + 27 0 0 5112 ccssew1 0 0 6 0 589 35 0 15 2 0 + 0 5141 pctip01 1538 3560 4766369 10024204 0 0 0 + 6351759 0 0 0 6040 oraprd0y 0 0 4 0 0 0 0 3 1 0 +0 6102 pimcp55 0 0 132 0 0 0 0 171 0 0 + 0 6723 oraprd0s 2390 5799 330034080 925707520 0 0 + 0 260013 0 0 0 6874 abmwrb1 0 0 8 0 316 0 0 28 1 0 + 0 7897 ccssjs1 0 0 13 0 350 0 0 32 4 0 + 0 7958 sybmrd04 853 2673 24337680 66644340 0 0 0 + 23963 0 0 0 8120 sussoa1 0 0 5 4 614 1191 0 18 5 +0 0 8358 ccssds1 0 0 0 26 0 70 0 43 9 0 + 0 8359 ccssas1 0 0 0 30 3 3211 0 99 18 +0 0 8463 ccssjs2 0 0 4 2 51 261 0 10 1 0 + 0 8537 ccssrr1 0 0 0 3 0 15 0 9 1 0 +0 8538 ccssch1 0 0 0 4 0 1 0 8 1 0 0 8757 sdbahh4 0 0 21 0 30 0 0 19 4 0 + 0 8853 sussfz1 0 0 10 0 4 0 0 21 2 0 + 0 9531 ccssrm1 0 0 0 139 0 27 0 574 4 0 + 0 9544 orarrd09 28 148 9568885 23818364 0 0 0 + 6708 0 0 0 9555 oratrd0u 0 0 3 0 0 0 0 2 0 0 +0 9607 oraprd0u 33 288 35538344 120434560 0 0 0 + 9509 0 0 0 9851 ppswp01 0 0 0 2 0 0 0 3 0 0 0 Jun 1 03:20 2007 TOTAL COMMAND SUMMARY FOR 05/2007 Page 1 TOTAL COMMAND SUMMARY COMMAND NUMBER TOTAL TOTAL TOTAL MEAN MEAN + HOG CHARS BLOCKS NAME CMDS KCOREMIN CPU-MIN REAL-MIN SIZE-K CPU-MIN +FACTOR TRNSFD READ TOTALS 32403945 2759238656.00 38978.47 11068820.00 70788.78 0.00 + 0.00 4362452336640 90950944 oracle 134522 1455575040.00 8026.35 2512456.00 181349.64 0.06 + 0.00 817459494912 51434296
In the foreach loop, I need to compare the Date after “MONTHLY USAGE FOR “ – in this case 05/2007 – to the 3rd argument I am passing to the perl script. If the dates do not match, I need the foreach loop to move on to process the next file in the directory. If the dates do match, I need to process the file (outputting lines from the MONTHLY USAGE FOR section) until the line that has “TOTAL COMMAND SUMMARY” in it – at this point, I need to exit the foreach loop and process the next file in the directory.
The perl code I had used to process a single PS Accounting Report file and output the appropriate records is as follows:
#!/usr/bin/perl use strict; use warnings; for my $file(“xsd00544.05”) { open (my $fh,'<',$file) or die "Cant open file $file: $!"; open (my $SORT,">","PSATst1.tab") or die "Can't open sort output file: + $!"; my @data; my $server; my $date; my $offset; while (my $line = <$fh> { chomp($line); if (($line =~ /MONTHLY USAGE FOR/) and ($. < 4)) { $offset = index($line,"MONTHLY USAGE FOR"); $date = substr($line,$offset+18,7); $server = substr($line,$offset+30,8); } last if ($line =~ /TOTAL COMMAND SUMMARY/); next unless $line =~ /^\d/; # Only process lines that beg +in with digits push @data,$line; } my @sorted = map { $_->[0] } sort { $a->[1] cmp $b->[1] } map [ $_, (split)[1] ], @data; print $SORT “$server \t $date \t $_\n” for @sorted; close $fh or die "Cant close file $file: $!"; close $SORT or die "Cant close sorted output file : $!"; }
The perl code I am testing to read multiple files from a directory, parse each file to determine if the report matches the date desired is as follows:
#!/usr/bin/perl ###################################################################### +## # # Testreaddpsa.pl - perl script to read a directory and multiple mon +thly # PSA Accounting Reports # # Execution requires 3 arguments # 1) Directory where PSA Monthly Accounting files reside # 2) File Specification string # 3) Date Required in format mm/yyyy # # Example: # perl Testreaddpsa.pl /prod/home/rvokulic/acct "*.*" "05/2007" # ###################################################################### +## use strict; use warnings; my $directory = $ARGV[0]; my $filespec = $ARGV[1]; my $datewant = $ARGV[2]; my $SORTFILES; my $index; my $offset; my $date; my $server; my $count; my %usage; my $files = 0; my @data; my @SORTFILES; opendir DIR, $directory or die "can't open $directory: $!\n"; my @FILES = glob("$directory/$filespec"); @SORTFILES=sort(@FILES); $count = @SORTFILES; ########################################################## # # Read All Files In Directory to Find Those That Match Date # ########################################################## foreach $SORTFILES (@SORTFILES) { open (my $fh,'<',$SORTFILES) or die "Cant open file $SORTFILES: $!"; open (my $SORT,">>","Tst1.tab") or die "Can't open sort output file: $ +!"; while (my $line = <$fh>) { chomp($line); next if ($line =~ /^$/ ); # skip if line begins with spaces last if ($line =~ /TOTAL COMMAND SUMMARY/); ## if (($line =~ /MONTHLY USAGE FOR/) and ($. < 4)) { $offset = index($line,"MONTHLY USAGE FOR"); $date = substr($line,$offset+18,7); $server = substr($line,$offset+30,8); last if ($date ne $datewant); ## } push @data, $line; my @sorted = map { $_->[0] } sort { $a->[1] cmp $b->[1] } map [ $_, (split)[1] ], @data; print $SORT "$server \t $date \t $_\n" for @sorted; } ## END of while loop continue { $files++ if eof; } close $fh or die "Cant close file $SORTFILES: $!"; close $SORT or die "Cant close file $SORT: $!"; } ## END of foreach loop closedir DIR;
This code is selecting the proper files that match the requested date, but no records are being output to the $SORT filehandle. I believe this has something to do with the scopes of the variables, but I am too new to perl to be sure.
I would greatly appreciate it if someone could give some insight as to what my problem might be.
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: Reading Directory & Passing Files in Directory Into a Foreach Loop
by atemon (Chaplain) on Sep 03, 2007 at 17:11 UTC | |
by rayv (Novice) on Sep 04, 2007 at 11:03 UTC | |
|
Re: Reading Directory & Passing Files in Directory Into a Foreach Loop
by Anonymous Monk on Sep 03, 2007 at 16:24 UTC | |
|
Re: Reading Directory & Passing Files in Directory Into a Foreach Loop
by Anonymous Monk on Sep 03, 2007 at 16:31 UTC | |
by jwkrahn (Abbot) on Sep 03, 2007 at 18:12 UTC |