f



printing the first line in many files that meets a certain condition

I'd like to print the first line from each of many files in which a
particular field meets a certain condition.  For example, I'd like to
print the lines that, going from top, contain the first negative value
in column 2 (line 3 in the exmaple below):

1.5992E-02, 1.6482E-03
1.6306E-02, 7.1307E-04
1.6656E-02, -3.9010E-05
1.7031E-02, -6.4005E-04
1.7437E-02, -1.1658E-03

What if I wanted to print all the lines which contain the last
positive value in column 2?  I know I would have to evaluate and store
the previous value, but have not been able to write a working
script...

Can it be done using an awk one-liner?

--z.entropic
0
z
3/19/2009 12:32:24 PM
comp.lang.awk 3447 articles. 0 followers. Post Follow

7 Replies
448 Views

Similar Articles

[PageSpeed] 47

On Thursday 19 March 2009 13:32, z.entropic wrote:

> I'd like to print the first line from each of many files in which a
> particular field meets a certain condition.  For example, I'd like to
> print the lines that, going from top, contain the first negative value
> in column 2 (line 3 in the exmaple below):
> 
> 1.5992E-02, 1.6482E-03
> 1.6306E-02, 7.1307E-04
> 1.6656E-02, -3.9010E-05
> 1.7031E-02, -6.4005E-04
> 1.7437E-02, -1.1658E-03

awk '$2<0 {print;exit}'

> 
> What if I wanted to print all the lines which contain the last
> positive value in column 2?  I know I would have to evaluate and store
> the previous value, but have not been able to write a working
> script...

awk '$2>0 {lastpos=$0} END{print lastpos}'

0
pk
3/19/2009 1:06:56 PM
z.entropic <subPlanck@excite.com> wrote:
> I'd like to print the first line from each of many files in which a
> particular field meets a certain condition.  For example, I'd like to
> print the lines that, going from top, contain the first negative value
> in column 2 (line 3 in the exmaple below):
> 
> 1.5992E-02, 1.6482E-03
> 1.6306E-02, 7.1307E-04
> 1.6656E-02, -3.9010E-05
> 1.7031E-02, -6.4005E-04
> 1.7437E-02, -1.1658E-03

FNR == 1 { p = 0 }
p != 0   { next }
$2 < 0   { print $0 ; p = 1 }

> What if I wanted to print all the lines which contain the last
> positive value in column 2?  I know I would have to evaluate and store
> the previous value, but have not been able to write a working
> script...

FNR == 1 && h != "" { print h ; h = "" }
$2 > 0              { h = $0 }
END                 { if (h != "") print h }
0
dave
3/19/2009 4:56:09 PM
Dave Gibson <dave+news002@gibson-hrd.abelgratis.co.uk.invalid> wrote:
> z.entropic <subPlanck@excite.com> wrote:
[...]
>> What if I wanted to print all the lines which contain the last
>> positive value in column 2?  I know I would have to evaluate and store
>> the previous value, but have not been able to write a working
>> script...
> 
> FNR == 1 && h != "" { print h ; h = "" }
> $2 > 0              { h = $0 }

Correction: 0 is positive

  !($2 < 0)           { h = $0 }
> END                 { if (h != "") print h }
0
dave
3/19/2009 5:04:54 PM
On Mar 19, 9:06=A0am, pk <p...@pk.invalid> wrote:
> On Thursday 19 March 2009 13:32, z.entropic wrote:
>
> > I'd like to print the first line from each of many files in which a
> > particular field meets a certain condition. =A0For example, I'd like to
> > print the lines that, going from top, contain the first negative value
> > in column 2 (line 3 in the exmaple below):
>
> > 1.5992E-02, 1.6482E-03
> > 1.6306E-02, 7.1307E-04
> > 1.6656E-02, -3.9010E-05
> > 1.7031E-02, -6.4005E-04
> > 1.7437E-02, -1.1658E-03
>
> awk '$2<0 {print;exit}'
>
>
>
> > What if I wanted to print all the lines which contain the last
> > positive value in column 2? =A0I know I would have to evaluate and stor=
e
> > the previous value, but have not been able to write a working
> > script...
>
> awk '$2>0 {lastpos=3D$0} END{print lastpos}'

Thaks, but these expressions print only the first occurrence...  they
don't loop over many files.

--z.e.
0
z
3/19/2009 8:43:50 PM
On Thursday 19 March 2009 21:43, z.entropic wrote:

> On Mar 19, 9:06 am, pk <p...@pk.invalid> wrote:
>> On Thursday 19 March 2009 13:32, z.entropic wrote:
>>
>> > I'd like to print the first line from each of many files in which a
>> > particular field meets a certain condition.  For example, I'd like to
>> > print the lines that, going from top, contain the first negative value
>> > in column 2 (line 3 in the exmaple below):
>>
>> > 1.5992E-02, 1.6482E-03
>> > 1.6306E-02, 7.1307E-04
>> > 1.6656E-02, -3.9010E-05
>> > 1.7031E-02, -6.4005E-04
>> > 1.7437E-02, -1.1658E-03
>>
>> awk '$2<0 {print;exit}'

with GNU awk:

awk '$2<0 {print;nextfile}' path/to/files/*

otherwise you can use Dave Gibson's code.

>> > What if I wanted to print all the lines which contain the last
>> > positive value in column 2?  I know I would have to evaluate and store
>> > the previous value, but have not been able to write a working
>> > script...
>>
>> awk '$2>0 {lastpos=$0} END{print lastpos}'
> 
> Thaks, but these expressions print only the first occurrence...  they
> don't loop over many files.

awk 'FNR==1&&lastpos{print lastpos} $2>0 {lastpos=$0} END{print lastpos}' *

0
pk
3/19/2009 9:00:23 PM
On Mar 19, 12:56=A0pm, dave+news...@gibson-hrd.abelgratis.co.uk.invalid
(Dave Gibson) wrote:
> z.entropic <subPla...@excite.com> wrote:
> > I'd like to print the first line from each of many files in which a
> > particular field meets a certain condition. =A0For example, I'd like to
> > print the lines that, going from top, contain the first negative value
> > in column 2 (line 3 in the exmaple below):
>
> > 1.5992E-02, 1.6482E-03
> > 1.6306E-02, 7.1307E-04
> > 1.6656E-02, -3.9010E-05
> > 1.7031E-02, -6.4005E-04
> > 1.7437E-02, -1.1658E-03
>
> FNR =3D=3D 1 { p =3D 0 }
> p !=3D 0 =A0 { next }
> $2 < 0 =A0 { print $0 ; p =3D 1 }
>
> > What if I wanted to print all the lines which contain the last
> > positive value in column 2? =A0I know I would have to evaluate and stor=
e
> > the previous value, but have not been able to write a working
> > script...
>
> FNR =3D=3D 1 && h !=3D "" { print h ; h =3D "" }
> $2 > 0 =A0 =A0 =A0 =A0 =A0 =A0 =A0{ h =3D $0 }
> END =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 { if (h !=3D "") print h }

Thanks, that's almost it.  However, since I like one-liners, how do I
use it as a line command, not an awk script? That is, the following
works:

$ ls *.z|xargs -l awk -f fn.awk

where fn.awk is

FNR =3D=3D 1 { p =3D 0 }; p !=3D 0 { next }; NR > 10 && $6 < 0 { print
FILENAME, $0; p =3D 1}

but this does not as it prints only the first occurrence...

$ cat *.z | awk 'FNR =3D=3D 1 { p =3D 0 }; p !=3D 0 { next }; NR > 10 && $6=
 <
0 { print FILENAME, $0; p =3D 1 }'

--z.e.
0
z
3/19/2009 9:01:31 PM
z.entropic <subPlanck@excite.com> wrote:
[...]
> Thanks, that's almost it.  However, since I like one-liners, how do I
> use it as a line command, not an awk script? That is, the following
> works:
> 
> $ ls *.z|xargs -l awk -f fn.awk
> 
> where fn.awk is
> 
> FNR == 1 { p = 0 }; p != 0 { next }; NR > 10 && $6 < 0 { print
> FILENAME, $0; p = 1}

Either:

awk -f fn.awk *.z

Or insert something like this:

#! /usr/bin/awk -f

as the first line of the script (change the path to match whichever
awk you're using), then chmod 755 the script and:

fn.awk *.z

> but this does not as it prints only the first occurrence...
> 
> $ cat *.z | awk 'FNR == 1 { p = 0 }; p != 0 { next }; NR > 10 && $6 <
> 0 { print FILENAME, $0; p = 1 }'

Cat writes the contents of its arguments to standard output.  To let awk
see the filenames, use:

awk '...' *.z

Incidentally, if you want to skip the first ten lines of each input
file the "NR > 10" part of your script should be "FNR > 10".
0
dave
3/19/2009 9:47:02 PM
Reply: