1. Yes, use a range with a 0
or ""
(= false, never match) end condition:
awk '<is_within_the_range>, 0'
where <is_within_the_range>
is your condition, which can be any expression, except for another range.
The start condition will not be evaluated again after the the 1st match:
$ seq 1 6 | awk '
function check(){ print "checking", $0; return $1 == 3 }
check(), 0
'
checking 1
checking 2
checking 3
3
4
5
6
2. If you don't like ranges, you can of course just do the whole thing C-like non-awkwardly, by printing all the lines explicitly once the condition was matched:
seq 1 6 | awk '$1==3 { do print; while (getline > 0) }'
3. Another solution that, according to the POSIX standard, should work with regular, seekable files (not with pipes!), but does not actually work with most awk implementations, would be to rely on awk setting the file pointer to the end of the last record upon exiting, as all POSIX utilities are required to:
seq 1 6 > file
{ awk '$1 == 3 { print; exit }'; cat; } < file
IMLE this only works with the awk
/nawk
from Solaris, not with gawk
, mawk
or the "one true awk" from *BSD.
4. Finally, you can write your own state machine (eg. by setting a flag then checking it) --in a slow high level language which already provides a nice streamlined interface for it-- but that's something too dumb to be worth dwelling upon.