Bash: One-liner to exit with the opposite status of a grep command?

后端 未结 11 2103
渐次进展
渐次进展 2021-02-06 22:08

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

相关标签:
11条回答
  • 2021-02-06 22:38

    Since someone already posted a Puppet solution, I might as well add how to invert a shell command run by Ansible:

      - name: Check logs for errors
        command: grep ERROR /var/log/cassandra/system.log
        register: log_errors
        failed_when: "log_errors.rc == 0"
    

    I.e. you just set the failed condition to the return code being 0. So this command fails if we do find the word ERROR in our logs.

    I chose this rather than grep -v as that also inverts grep's output, so we would receive all DEBUG/INFO/WARN lines in log_errors.stdout_lines which we do not want.

    0 讨论(0)
  • 2021-02-06 22:42
    [ $(grep -c -P "STATUS: (?!Perfect)" recess.txt) -eq 0 ]
    
    0 讨论(0)
  • 2021-02-06 22:43

    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 have grep 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:

    grep -vqP "STATUS: (?!Perfect)" recess.txt
    

    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:

    awk '/STATUS: / && ! /Perfect/{exit 1}' recess.txt
    

    If you decide you want the output that grep would have provided, you can do:

    awk '/^STATUS: / && ! /Perfect/{print;ec=1} END{exit ec}' recess.txt
    
    0 讨论(0)
  • 2021-02-06 22:45

    The problem with the grep answers is that if the file is empty you also get a clean response, as if the file had a perfect. So personally I gave up on grep for this and used awk.

    awk 'BEGIN{ef=2}; /STATUS: Perfect/{ ef=0;}; /STATUS: Busted/{ print;eff=3;}; END{exit (ef+eff)}' a.txt ; echo $?
    
    This has exit status:
     0 :  Perfect and !Busted
     2 : !Perfect and  Busted
     3 :  Perfect and  Busted
     5 : !Perfect and !Busted
    
    0 讨论(0)
  • 2021-02-06 22:48

    Just negate the return value.

    ! grep -P "STATUS: (?!Perfect)" recess.txt
    
    0 讨论(0)
提交回复
热议问题