18

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?

23

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
  • 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? – Stefan Lasiewski Jul 13 '11 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. – Gilles 'SO- stop being evil' Jul 13 '11 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. – Stefan Lasiewski Jul 13 '11 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". – Skippy le Grand Gourou Oct 31 '19 at 13:37
8

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
    awk -F: 'NF != 7 {exit 1}' will do the same. – Stéphane Chazelas Dec 13 '19 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.