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
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 theEND {exit err}'
terminates the script. Is there a way to set the return status without exiting?Stefan Lasiewski– Stefan Lasiewski2011年07月13日 17:38:48 +00:00Commented Jul 13, 2011 at 17:38 -
6@StefanLasiewski
exit err
terminates awk, it doesn't terminate the script. Do you haveset -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, useif awk ...; then echo ok; else echo fail; fi
.Gilles 'SO- stop being evil'– Gilles 'SO- stop being evil'2011年07月13日 22:50:17 +00:00Commented 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.Stefan Lasiewski– Stefan Lasiewski2011年07月13日 23:21:15 +00:00Commented Jul 13, 2011 at 23:21 -
1If 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– Skippy le Grand Gourou2019年10月31日 13:37:15 +00:00Commented Oct 31, 2019 at 13:37
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
}
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
-
3
awk -F: 'NF != 7 {exit 1}'
will do the same.Stéphane Chazelas– Stéphane Chazelas2019年12月13日 21:01:12 +00:00Commented Dec 13, 2019 at 21:01