In awk, can you use a pattern AND an END block together?

Viewed 256

In awk, you can perform an action for a given pattern, like:

echo foo | awk '/foo/ {print "foo"}'

or you can perform an action at the end of the input, like:

echo foo | awk 'END {print "END"}'

But it does not appear to be possible to do both, like:

# echo foo | awk '/foo/ || END {print "foo or END"}'
awk: syntax error at source line 1
 context is
    /foo/ || >>>  END <<<  {print "foo or END"}
awk: bailing out at source line 1

Is this possible?

4 Answers

No. Do this instead:

awk '
/foo/ { prtInfo() }
END   { prtInfo() }
function prtInfo() { print "foo or END" }
'

you can try this workaround

awk '{Last=$0} END{ if( Last ~ /foo/) print "action if" }' YourFile

but it's only for last line of last file

this might be simpler

$ awk '/foo/{exit} END{print "foo or END"}'

exit will run the END block, so you don't need to repeat the statement.

No you cannot do such a thing. The END statements are executed when the last line has been processed and similar to BEGIN they are special forms of patterns.

Overall Program Structure

An awk program is composed of pairs of the form:

pattern { action }

Either the pattern or the action (including the enclosing brace characters) can be omitted.

Patterns

A pattern is any valid expression, a range specified by two expressions separated by a comma, or one of the two special patterns BEGIN or END.

Special Patterns

The awk utility shall recognize two special patterns, BEGIN and END. Each BEGIN pattern shall be matched once and its associated action executed before the first record of input is read-except possibly by use of the getline function (see Input/Output and General Functions) in a prior BEGIN action-and before command line assignment is done. Each END pattern shall be matched once and its associated action executed after the last record of input has been read. These two patterns shall have associated actions.

BEGIN and END shall not combine with other patterns. Multiple BEGIN and END patterns shall be allowed. The actions associated with the BEGIN patterns shall be executed in the order specified in the program, as are the END actions. An END pattern can precede a BEGIN pattern in a program.

source: awk POSIX standard

The statement

/foo/ || END { action }

is thus not allowed as it combines END with another pattern.

See the answer of Ed Morton for an elegant solution.

Related