'awk search for string and set exit code if it exists

I want to check if a line exists between two addresses and return an exit code 0 if it exists and 1 if it does not. I think I've got one possible example working, but I'm wondering if there is a cleaner way to do it; or perhaps a different tool that's also common on RedHat.

My Command:

awk 'BEGIN{found=1}NR==1,/^Match/{ if ( $0 == "PermitRootLogin yes" ) \
    { found=0 } }END { exit found }' /etc/ssh/sshd_config
awk


Solution 1:[1]

awk '/^PermitRootLogin yes$/{f=1} /^Match/{exit} END{exit !f}' /etc/ssh/sshd_config

Solution 2:[2]

Question
@EdMorton
I was after clarification on the use of '!f' in your solution and how this gives the correct exit 0 code? Specifically, what the negation '!' part is doing?

UPDATE
OK, I've finally wrapped my head around the exclamation mark on the awk exit code.

For anyone else out there for whom this wasn't immediately obvious too, the way to think of the exclamation point is not as a negation but as an invert function.

  1. The truth is, gawk/awk returns EXIT_SUCCESS ('0') even if your regex does not match. Try it yourself. No match = no output but still shell exit code 0.

    Awk will however, perform a command based on whether the regex pattern is found or not, so we use that fact to perform a variable assignment ('f=1' in this case) if our conditions have been met. The conditions in my example below, are: - if NR is equal to line 6 AND the regex pattern is matched.

  2. Here's the tricky part. Since EXIT_SUCCESS is a '0' for applications and we gave our flag variable f a numerical value of '1', we need to invert this number with the exclamation mark in front of the exit variable !f. Now we get a '0' exit code from awk if our regex pattern was successful and a '1' exit code if it did not match.

One other observable truth worth mentioning here:

Awk's default action on a regex pattern match is to print the whole line matching the pattern. Once we tell awk to perform a task, like setting a flag {f=1} or giving the {exit} command, awk no longer prints the matched regex pattern to stdout. Instead, awk now performs the task we told it to and quietly exits.

TODO=~/Dropbox/todo.txt
awk 'NR==6 && /due:[0-9]{4}-[0-9]{2}-[0-9]{2}/{exit;f=1} END {exit !f}'  \
$TODO ; echo $? 
0

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Ed Morton
Solution 2