Operating System - HP-UX
1833749 Members
2811 Online
110063 Solutions
New Discussion

Re: Need the help with awk or Perl again.

 
SOLVED
Go to solution
Belinda Dermody
Super Advisor

Need the help with awk or Perl again.

have this file like below, all org_code lines are followed by 6 additional lines. What I need in the final format is AFC|125568|3621|10788|125568|3621|10788
DUKE|150791|0|0|150791|0

A pipe delimited file. The number of values in each line will always be the same

value of org_code, AFC
count of y MOL 125568
count of r MOL 3621
count of b MOL 10788
count of y KAU 125568
count of r KAU 3621
count of b KAU 10788

value of org_code, DUKE
count of y MOL 150791
count of r MOL 0
count of b MOL 0
count of y KAU 150791
count of r KAU 0
count of b KAU 0
19 REPLIES 19
Tim D Fulford
Honored Contributor

Re: Need the help with awk or Perl again.

awk '{printf "%s|", $NF}; END '{printf "\n"}'

Tim
-
curt larson_1
Honored Contributor

Re: Need the help with awk or Perl again.

this should get you started

cat file | awk '
/value of/ {printf("%s",NF);}
/count of b/ {
count++;
printf("%s",NF);
if (count == 2 ) {
printf("\n");
count = 0;
next
}
/count of/ {printf("%s",NF);}'
Mark Grant
Honored Contributor

Re: Need the help with awk or Perl again.

If you really want perl, how about this nasty bit of code. Sorry but I can't really get my perl head together today. It does work however

#!/usr/bin/perl

open FILE,"datafile";

while($line=){
chomp($line);
next if $line eq "";
($DATA)=($line=~/.+\b(.+)/);
if($line =~ /value of org_code/){
print "\n";
} else {
print "|";
}
print $DATA;
}
print "\n";
Never preceed any demonstration with anything more predictive than "watch this"
curt larson_1
Honored Contributor

Re: Need the help with awk or Perl again.

oops forgot the seperators

cat file | awk '
/value of/ {printf("%s|",NF);}
/count of b/ {
count++;
if ( count == 2 ) {
printf("%s\n",NF);
count = 0;
}else {
printf("%s|",NF);
}
next;}
/count of/ {printf("%s|",NF);}'
Mark Grant
Honored Contributor

Re: Need the help with awk or Perl again.

Slightly shorter but still ugly

#!/usr/bin/perl

open FILE,"datafile";

while(){
next if $_ eq "";
($DATA)=($_=~/.+\b(.+)/);
if(/value of org_code/){
print "\n";
} else {
print "|";
}
print $DATA;
}
print "\n";
Never preceed any demonstration with anything more predictive than "watch this"
Belinda Dermody
Super Advisor

Re: Need the help with awk or Perl again.

Mark, I have tried both of your perl programs and they both come out with the same results
AFC| | | | | |
DUKE| | | | | |

I get the ORg but no data in between the pipes.
Belinda Dermody
Super Advisor

Re: Need the help with awk or Perl again.

Curt both of your awk scripts gives the good old bail error at the end, I have tried awk and nawk with the same results and I compared line for line, I prefer to use awk because of other stuff that I have to do with the file.....
Hein van den Heuvel
Honored Contributor
Solution

Re: Need the help with awk or Perl again.

- (re)start when a line is seen beginning with 'val'
- ignore if empty
- make seperator newline if more than 5 fields, bar if not.
- print last field and seperator.


awk '/^val/{x=0};(NF) {n=(x++>5)? "\n":"|"; printf "%s%s", $NF,n;}' < yourfile


In perl with a little more robust parsing:
- start fresh line if line begins with 'val'
- add seperator bar and field to line if line begins with count
- print line if more than 5 counts seen.

perl -ne 'if (/^val.*,\s+(\w+)$/){$l=$1; $nf=0}; if (/^cou.*\s(\w+)$/){$l.="|$1"; print "$l\n" if (++$nf>5)}' < yourfile


Hein.
Marvin Strong
Honored Contributor

Re: Need the help with awk or Perl again.

#!/usr/bin/perl

open F, "input" or die "$!";
while () {
print "\n" && next if ($_ eq "");
@data = split/\s+/;
if (/^value/) {
print "$data[3]|";
}else{
print "$data[4]|";
}
}


this should do it.
Marvin Strong
Honored Contributor

Re: Need the help with awk or Perl again.

oops minor bug in that last one.

here ya go.

#!/usr/bin/perl

open F, "input" or die "$!";
while () {
if (/^$/) { print "\n"; next; }
@data = split/\s+/;
if (/^value/) {
print "$data[3]|";
}else{
print "$data[4]|";
}
}
Kent Ostby
Honored Contributor

Re: Need the help with awk or Perl again.

put your data in datafile and the awk commands in useme.awk then run:

awk -f useme.awk < datafile

Put the following in useme.awk:

BEGIN {linecnt=0;}
NF<4{next;}
/^value /{if (linecnt!=0)
{print daline;};
daline=$4;linecnt++;next;}
/^count/{daline=daline"|"$5;next}
END{print daline;}
"Well, actually, she is a rocket scientist" -- Steve Martin in "Roxanne"
Jean-Luc Oudart
Honored Contributor

Re: Need the help with awk or Perl again.

awk solution :

#!/bin/sh

awk '
{
if(substr($0,1,17)=="value of org_code") {
split($0,tab,",");
printf("%s",tab[2]);
for(i=1; i < 6;i++) {
getline;
printf("|%d",$5);
}
printf("\n");
}
}'

Regards
Jean-Luc
fiat lux
curt larson_1
Honored Contributor

Re: Need the help with awk or Perl again.

James,

Curt both of your awk scripts gives the good old bail error at the end.

Could you give the error that your receiving?
I'd be glad to help you find the error.

I was able to run this script without any problems. It does have two modificaitons, $NF and next in the action of /value of/, but other then that it is the same as before.

cat file | awk '
/value of/ {printf("%s|",$NF);next;}
/count of b/ {
count++;
if ( count == 2 ) {
printf("%s\n",$NF);
count = 0;
}else {
printf("%s|",$NF);
}
next;}
/count of/ {printf("%s|",$NF);}'
Belinda Dermody
Super Advisor

Re: Need the help with awk or Perl again.

Curt thanks for the followup, the new one works the way the that I wanted it to and thanks for your effort, that is why the HP forums are the best, I would stil be waiting for SUNSOLVE to get back to me.
Marvin Strong
Honored Contributor

Re: Need the help with awk or Perl again.

just noticed mine didn't do exactly what you wanted. as it had a trailing |

here is an easy commandline version.

#perl -nae 'if(/^$/){print "\n";next;}if(/^value/){print "$F[3]";}else{print "|$F[4]"}' input_file

and a corrected version of my above posts.

open F, "input" or die "$!";
while () {
if (/^$/) { print "\n"; next; }
@data = split/\s+/;
if (/^value/) {
print "$data[3]";
}else{
print "|$data[4]";
}
}
close F;
Belinda Dermody
Super Advisor

Re: Need the help with awk or Perl again.

Thanks Marvin, yours works but it just makes one continuous line of data....

AFC|125568|3621|10788|125568|3621|10788DUKE|150791|0|0|150791|0|0EXR|26009|8|322|889WRN|80759|422|3129|80759|422|3129YALE|144122|8|272|144122|8|272
Marvin Strong
Honored Contributor

Re: Need the help with awk or Perl again.

hmm it works fine for me here.

I know the first one I posted did only do one line of output. But the last two should work.

# perl -nae 'if(/^$/){print "\n";next;}if(/^value/){print "$F[3]";}else{print "|$F[4]"}' input
AFC|125568|3621|10788|125568|3621|10788
DUKE|150791|0|0|150791|0|0

using perl 561

I attached my script and with it the command line commmented inside it.

Hopefully its useful for you.

Mark Grant
Honored Contributor

Re: Need the help with awk or Perl again.

I have to say, both my scripts worked OK for me. The only thing that would make it come out is if the /.+\b(.+)/ isn't matching the data. Should do though *shrug*
Never preceed any demonstration with anything more predictive than "watch this"
Marvin Strong
Honored Contributor

Re: Need the help with awk or Perl again.

oh one more thing, mine does assume there is a blank line between the last count and the next value.

if that is not the case all the time. then it will do one continuous line of output.
As that blank line is what determines the newline.

the code is easy enough to change if that blank line is not always present.

if you need it modified so that blank line isn't required, It can be easily changed.