21

This is a followup to my earlier question.

I am validating the number of fields in /etc/passwd using this handy snippit. In the following example, the users 'fieldcount1' and 'fieldcount2' have the wrong number of fields:

$ awk -F: ' NF!=7 {print}' /etc/passwd
fieldcount1:x:1000:100:fieldcount1:/home/fieldcount1:/bin/bash::::
fieldcount2:blah::blah:1002:100:fieldcount2:/home/fieldcount2:/bin/bash:
$ echo $?
0

As you'll notice, awk will exit with an return status of 0. From it's standpoint, there are no problems here.

I would like to incorporate this awk statement into a shell script. I would like to print all lines which are error, and set the return code to be 1 (error).

I can try to force a particular exit status, but then awk only prints a single line:

$ awk -F: ' NF!=7 {print ; exit 1}' /etc/passwd
fieldcount1:x:1000:100:fieldcount1:/home/fieldcount1:/bin/bash::::
$ echo $?
1

Can I force awk to exit with a return status of '1', and print all lines which match?

3 Answers 3

29

Keep the status in a variable and use it in an END block.

awk -F: 'NF != 7 {print; err = 1}
         END {exit err}' /etc/passwd
4
  • Very good. However I am running into problems incorporating this into a bash script. I am trying to capture the return status of this awk statement by adding something like ; echo $? after this awk statement. However, echo $? is never run because the END {exit err}' terminates the script. Is there a way to set the return status without exiting? Jul 13, 2011 at 17:38
  • 6
    @StefanLasiewski exit err terminates awk, it doesn't terminate the script. Do you have set -e in that script, by any chance? If so, you've told the shell to exit if a command returns a nonzero status; if you want to test the status, use if awk …; then echo ok; else echo fail; fi. Jul 13, 2011 at 22:50
  • @Giles : Yes, this script does have set -e set. That explains the strange behavior that I'm seeing. Thanks for pointing that out. Jul 13, 2011 at 23:21
  • 1
    If you plan to use the output with bash's && operator, it's worth keeping in mind that "0 is true but false is 1 in the shell". Oct 31, 2019 at 13:37
9

I was looking for something similar to Grep, where it will exit 1 if a match is not found. Here is the equivalent with Awk:

#!/usr/bin/awk -f
BEGIN {
   b1 = 1
}
index($0, "sunday") > 0 {
   b1 = 0
   print
}
END {
   exit b1
}
0

This does not answer the OP exact requirements, but if you only care about the return code, and not needing to print the lines that match, similar to grep -q, then you can modify @geekasaur answer to exit after the first match, which for huge input files would save time if the error is early in the file. Hopefully /etc/passwd does not qualify for you!

awk -F: 'NF != 7 {err = 1; exit;}
     END {exit err}' /etc/passwd
1
  • 1
    awk -F: 'NF != 7 {exit 1}' will do the same. Dec 13, 2019 at 21:01

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.