1834231 Members
2352 Online
110066 Solutions
New Discussion

AWK report format query

 
Ranjit_1
New Member

AWK report format query

I have an input file (refer to extract below) which I am attempting to convert into an output file as set-out below.

Is this a task suitable for awk to work on? I have attempted using an approach which searches for the expression "pool" and gets the subsequent TAPE lines - counting each occurance under the respective pool heading.

I've ran into problems and do not get the desired result - in particular the "zero" tape occurances are proving problematic to work around.

Can any one help? Help wound be appreciated.

Thanks in advance.


=====================================
INPUT DATA FILE:

TAPE SILO MEDIA INVENTORY
-------------------------

SALES_BACKUP pool

TAPE0050
TAPE0059
TAPE0072

DATABASE_LOG pool

FINANCE pool

TAPE0426
TAPE0021

SCRATCH pool

TAPE0153
TAPE0155
TAPE0159
TAPE0162

DEVELOPMENT pool

TEST pool

====================================

DESIRED OUTPUT FILE:

SALES_BACKUP pool: 3
DATABASE_LOG pool: 0
FINANCE pool: 2
SCRATCH pool: 4
DEVELOPMENT pool: 0
TEST pool: 0

====================================

10 REPLIES 10
Rodney Hills
Honored Contributor

Re: AWK report format query

Enter this perl routine into a file (like myprog.pl)-

while(<>) {
/^(\S+)\s+pool/ && do { $cur=$1; $cnt{$cur}=0; }
/^TAPE/ && do { $cnt{$cur}++; }
}
foreach $pool (sort keys %cnt) {
print "$pool pool: $cnt{$pool}\n";
}

Then run passing the input file and output file-

perl myprog.pl yourinput >youroutput

While awk is good for simple text processing, perl is the "king".

HTH

-- Rod Hills
There be dragons...
harry d brown jr
Honored Contributor

Re: AWK report format query



awk 'BEGIN {firsttime=1;hits=0;prevhit=""}
{
if (match($0,/^$/)) {next;}
if (match($0,/^TAPE[0-9][0-9][0-9][0-9]/)) {hits+=1;}
if (match($0,/.* pool$/)) {
if (firsttime) {firsttime=0;} else {
printf("%s pool: %d\n",prevhit,hits);
hits=0;
}
prevhit=$1;
}
}
END {printf("%s pool: %d\n",prevhit,hits);}'


live free or die
harry
Live Free or Die
H.Merijn Brand (procura
Honored Contributor

Re: AWK report format query

Or in a oneliner:

# perl -nle'chomp;/\s+pool$/and$p{$p=$_}=0,next;/\S/&&$p{$p}++}END{print"$_: $p{$_}" for keys%p' infile
DATABASE_LOG pool: 0
SALES_BACKUP pool: 3
FINANCE pool: 2
DEVELOPMENT pool: 0
TEST pool: 0
SCRATCH pool: 4
Enjoy, Have FUN! H.Merijn
Vincent Fleming
Honored Contributor

Re: AWK report format query

You should be able to use the BEGIN{} section in awk to zero your counters.

For example,

BEGIN{ salespool=0; databasepool=0; financepool=0; scratchpool=0; develpool=0; testpool=0; }{ ...

If you initialize your counters like this, then even the zero ones should come out zero.

good luck,

Vince
No matter where you go, there you are.
harry d brown jr
Honored Contributor

Re: AWK report format query


Procura,

Your output produced this:

TEST pool: 0
FINANCE pool: 2
SALES_BACKUP pool: 3
: 2
DATABASE_LOG pool: 0
DEVELOPMENT pool: 0
SCRATCH pool: 4


The : 2 looks bad :-)

live free or die
harry
Live Free or Die
harry d brown jr
Honored Contributor

Re: AWK report format query

Vincent,

With the awk I posted it does use a BEGIN and doesn't require temp counters for "pool"'s.

live free or die
harry
Live Free or Die
Vincent Fleming
Honored Contributor

Re: AWK report format query

Very true, Harry. It was just a thought, given that they were having trouble with the zero counters.

Also... your post wasn't there when I started typing...

I thought the perl solutions were pretty thoughtful - I don't yet think of using perl, as I'm just learning it. Nice idea, and probably better suited to the task.

I should spend some more time reading up on perl.

Cheers,

Vince
No matter where you go, there you are.
H.Merijn Brand (procura
Honored Contributor

Re: AWK report format query

Hmm, I just cut-n-pasted his example, and indeed got the output I posted.

Which version of perl do you use? I might have been using the 'for' as a statement modifier, but I don't remember in which version that was introduced.

chopped up for increased readability I did

# perl -nle '
chomp;
/\s+pool$/ and $p{$p = $_} = 0, next;
/\S/ && $p{$p}++
}
END {
print "$_: $p{$_}" for keys %p
' infile

In a `real' script that could look like (but then you could use Rodney's example as well):

--8<---
#!/usr/bin/perl

use strict;
use warnings;

my %p = ();
my $p;
while (<>) {
chomp;
my $p;
if (/\s+pool$/) {
$p{$p = $_} = 0;
next;
}
/\S/ and $p{$p}++;
}

foreach my $k (keys %p) {
print "$k: $p{$k}";
}
-->8---
Enjoy, Have FUN! H.Merijn
H.Merijn Brand (procura
Honored Contributor

Re: AWK report format query

--8<---
#!/usr/bin/perl

use strict;
use warnings;

my %p = ();
my $p;
while (<>) {
chomp;
my $p; # <---- Strike this line!!
if (/\s+pool$/) {
$p{$p = $_} = 0;
next;
}
/\S/ and $p{$p}++;
}

foreach my $k (keys %p) {
print "$k: $p{$k}";
}
-->8---
Enjoy, Have FUN! H.Merijn
Joseph A Benaiah_1
Regular Advisor

Re: AWK report format query

Ranjit,

Try this awk script:

#!/usr/bin/sh

awk '
{ buf[NR] = $0 }

END {
size = NR

for ( i = 1 ; i <= size ; i++ )
{
if ( buf[i] ~ /pool$/ )
{
pool = buf[i]
j = 0
}

if ( buf[i] ~ /^TAPE[0-9]/ )
{
++j
}

if ( ( buf[i+1] ~ /pool$/ && pool != "" ) || i == size )
{
sum = j
print pool ": " sum
}
}
}' media.out

Change the name of media.out to be the name of your input file.

Cheers,

Joseph