How can I reduce the following bash script?
grep -P "STATUS: (?!Perfect)" recess.txt && exit 1
exit 0
It seems like I should be able to do it with a single command, but I have a total of 3 here.
My program should:
- Read recess.txt
- Exit 1 (or non-zero) if it contains a line with "STATUS: " of NOT "Perfect"
- Exit 0 if no such line exists (i.e. all "STATUS: " lines are "Perfect")
The answer award goes to the tightest script. Thanks!
Example files
Program should have exit status 0 for this file:
FILE: styles.css
STATUS: Perfect!
FILE: contour-styles.css
STATUS: Perfect!
Program should have exit status 1 (or non-zero) for this file:
FILE: styles.css
STATUS: Perfect!
FILE: contour-styles.css
STATUS: Busted
FAILURES: 1 failure
Id's should not be styled
1. #asdf
To make it work with
set -e
surround it in a sub-shell with(
and)
:Use the special
?
variable:(But note that
grep
may also return 2, so it's not clear what you'd want to occur in such cases.)You actually don't need to use
exit
at all. Logically, no matter what the result of grep, your script is going to exit anyway. Since the exit value of a shell script is the exit code of the last command that was run, just havegrep
run as the last command, using the-v
option to invert the match to correct the exit value. Thus, your script can reduce to just:EDIT:
Sorry, the above does not work when there are other types of lines in the file. In the interest of avoiding running multiple commands though,
awk
can accomplish the entire shebang with something like:If you decide you want the output that grep would have provided, you can do:
I came across this, needing an
onlyif
statement for Puppet. As such, Tgr's bash solution wouldn't work, and I didn't want to expand the complexity as in Christopher Neylan's answer.I ended up using a version inspired by Henri Schomäcker's answer, but notably simplified:
Which very simply inverts the exit code, returning success only if the text is not found:
test 0 -eq 1
will return 1.test 1 -eq 1
will return 0.test 2 -eq 1
will return 1.Which is exactly what I wanted: return 0 if no match is found, and 1 otherwise.
Just negating the return value doesn't work in a set -e context. But you can do:
if anyone gets here looking for a bash return code manipulation:
this will return
0
(success) when grep finds nothing, and return123
(failure) when it does. The parenthesis are in case anyone test it as is on the shell prompt. with parenthesis it will not logout on the exit, but just exit the subshell with the same error code.i use it for a quick syntax check on js files: