1832880 Members
2490 Online
110048 Solutions
New Discussion

AWK Help

 
Chris Frangandonis
Regular Advisor

AWK Help

Hi All,

Is there a way that I can printf certain fields ($?), starting from (4 K) from file.
Currently I am using awk '{if($0~/4 K/){printf "\n%s %s\n",sep,$0;sep="\n";next}{printf "%s %s %s %s" ,$1,$5...etc , with no luck.
Any solutions will be appreciated.


Thanks
Chris
15 REPLIES 15
Mike Higgs
Occasional Advisor

Re: AWK Help

Hi Chris,
could you paste in a small extract of your file as I'm not sure what you want exactly. Is 4 K on a line on it's own? I tried opening the attachment but am not sure how it should really look.

Mike
Chris Frangandonis
Regular Advisor

Re: AWK Help

Hi Mike

Thanks for you reply.
Here is the head of the text file

D
808 h
J
808 g
b
J
4 K <-------- is maybe my common piont
28295948 A <------ Field 1
10 0123261078 A <----- Field 2
7 3070300 A
7 tpr+:09 E
1073920992 C
SL b
J
1 D
3 Q

etc........

Thanks
Chris
Steve Lewis
Honored Contributor

Re: AWK Help

awk '/4K/{getline;print;getline;print}' filename
Graham Cameron_1
Honored Contributor

Re: AWK Help

Chris
Not sure what you mean because first you talk about fields but then in your later example you are really talking lines.

Steve's post will print the next 2 lines after each time it finds the string /4K/, (except I think you wanted a space -ie /4 K/) because getline gets the next line, and print with no arguments prints the entire line (as does print $0).

If you want to operate on fields within lines, that's when to use $1, $2 etc, up to $NF.

So, if you wanted to print the 2nd field of the line after /4 K/. and the 3rd and 4th fields of the line after that:

awk '
/4 K/ {next; printf ("%s\n", $2);next; printf ("%s %s\n", $3, $4) }
'

Semicolons are needed to separate commands on the same line, but if you put them on separate lines you don't need them.

Hope this helps

-- Graham
Computers make it easier to do a lot of things, but most of the things they make it easier to do don't need to be done.
Mike Higgs
Occasional Advisor

Re: AWK Help

So, do you want fields from the two lines following the "4 K" line?

Mike
Chris Frangandonis
Regular Advisor

Re: AWK Help

Hi All,

Thanks once again.

Mike/Steve/Graham)I want to be able to select any fields after the first /4 K/ and the next /4 K/ and so on until EOF

The End result should look like this from the text file supplied.

1)28295948 0123261078 3070300 tpr+:09 1073920992 .. .. etc
2)75804243 0137411100 0137534401 tnpt:03
1073942316 .. .. etc
3)55491852 .. .. .. .. etc


Hope this helps.

Thanks
Chris

Graham Cameron_1
Honored Contributor

Re: AWK Help

Chris

Still not clear.
From the example you just gave, after the first /4 K/, you want field 1 of the next line, then field 2 of the next line, field 2 of the next line, but then what ??

The 2nd /4 K/ in your attachment is followed by "41490197 A", but your example is different.

If you can give us the definitive rules, we can code it for you...

-- Graham
Computers make it easier to do a lot of things, but most of the things they make it easier to do don't need to be done.
Chris Frangandonis
Regular Advisor

Re: AWK Help

Graham,

Your are correct. I missed a line and yes What I am trying to achieve is, after the /4 K/ is found line up the fields if possible(see attachment), use printf for whatever field, look for the next /4 K/ and repeat the steps as above, until EOF.

Hope this makes sense.

Thanks Once Again
Chris
Jakes Louw
Trusted Contributor

Re: AWK Help

Awk, he sed.....

Wot's wrong, Chris, can't you program....

(sorry chaps, private joke between me and Fandango....)
Trying is the first step to failure - Homer Simpson
Elmar P. Kolkman
Honored Contributor

Re: AWK Help

It would be something like this then:
awk '/4 K/ { getline; printf "%s",$1; getline; printf " %s\n",$2}'


Or do you mean this:
awk '/4 K/ { getline; printf "%s",$0; getline; printf" %s\n",$0}'

You can change the printf statements to whatever you like, of course. The getline will just replace all argument fields...
Every problem has at least one solution. Only some solutions are harder to find.
Chris Frangandonis
Regular Advisor

Re: AWK Help

Hi Elmar,

Thanks for your reply.

By doining { getline; printf "%s",$0;getline; printf" %s\n",$0}', your are getting the next two fields which is not what I am looking for. I must be able to select any fields after /4 K/.

Thanks Chris
Elmar P. Kolkman
Honored Contributor

Re: AWK Help

What do you mean any field?!

Do you mean something like this then?

awk 'BEGIN {field=""}
/4 K/ if (field != "") { ; field="";next;}
{field = field + $0 }
END { }'

This will get the lines between '4 K' records into the field var. You can do with that what you want then.
Every problem has at least one solution. Only some solutions are harder to find.
Chris Frangandonis
Regular Advisor

Re: AWK Help

Elmar,

What I mean is that when /4 K/ is found, from awk '{if($0~/4 K/){printf "\n%s %s\n",sep,$0;sep="\n";next}{printf "%s" ,$0}| awk '{print $5,$15,$16}' it returns an error "cannot be longer than 3000 bytes.

If you look at the attachment you will see that the lines a quit long. As for the result, I would like to see the output as:

(after the first /4 K/ )
0123268282 20040112180457 0123070300 41490197 I ds09 tpr+:09 tpr+:09.ds09.0000289.00017900.20040112220000
(after the next /4 K/)
0145381447 20040112233314 0860007249 55491852 B ds09 trt+:03 trt+:03.ds09.0000022.00017970.20040113044000
(after the next /4 K/)
0137412701 20040112221150 ........etc.

I may choose futher more fields, for the above is an example.

If you have a better solution please post it.


Thanks
Chris

Hope this helps

Rodney Hills
Honored Contributor

Re: AWK Help

The attachment you provided in the recent post is different from your first.

Also the example you display doesn't match up with the line after the first /4 K/, but maybe the second /4 K/.

If the fields do exist on each line, why couldn't you use "cut" to select the fields you want?

example-
cut -f 12,18,24 youroutput

This would allow you to select the fields you want.

If the first file you attached represents the true data, then a tool like "perl" could be used to slurp up the data, organize it, then print out the arrangement you want.

Your definition of the problem is very hard to follow...

-- Rod Hills
There be dragons...
Elmar P. Kolkman
Honored Contributor

Re: AWK Help

Tried to reply yesterday, but had problems contacting the forums.

To solve your problem, put the fields between the '4 K' lines in an array and use that to select the fields. But first check if awk can work with the input file. You can do this like this:
cat datafile | awk '{print $1}' > /dev/null

It might fail, which means awk might be useless (don't see options to use longer recordlength) and you might consider perl.

If that succeeds, your script will become something like this:
awk '/4 K/ { if (idx > 0) {
printf ("$s $s $s $s\n",fields[1],fields[5],fields[6],fields[15]);
while (idx > 0) {
fields[idx]="";
idx--;
}
}
printf("4 K\n");
started=1;
}
{ if (started) {
i=0;
while (i < NF) {
idx++;
i++;
fields[idx]=$i
}
}
}'
Every problem has at least one solution. Only some solutions are harder to find.