Bash:以grep命令的相反状态退出一行?

Sea*_*son 28 regex bash grep exit-code exit

如何减少以下bash脚本?

grep -P "STATUS: (?!Perfect)" recess.txt && exit 1
exit 0
Run Code Online (Sandbox Code Playgroud)

看起来我应该可以用一个命令来完成它,但我这里总共有3个.

我的程序应该:

  • 阅读recess.txt
  • 退出1(或非零)如果它包含"STATUS:"NOT"Perfect"的行
  • 如果不存在这样的行,则退出0(即所有"STATUS:"行都是"完美")

答案奖授予最严格的剧本.谢谢!

示例文件

计划应该有退出状态0此文件:

FILE: styles.css 
STATUS: Perfect!

FILE: contour-styles.css
STATUS: Perfect!
Run Code Online (Sandbox Code Playgroud)

程序应该具有此文件的退出状态1(或非零):

FILE: styles.css 
STATUS: Perfect!

FILE: contour-styles.css
STATUS: Busted 
FAILURES: 1 failure

Id's should not be styled
       1. #asdf
Run Code Online (Sandbox Code Playgroud)

Tgr*_*Tgr 32

只是否定返回值.

! grep -P "STATUS: (?!Perfect)" recess.txt
Run Code Online (Sandbox Code Playgroud)

  • 如果使用(),则使用set -e.看我的回答. (5认同)
  • @wedi`猫休息.txt | ( ! grep -P "STATUS: (?!Perfect)" )` 可以工作(它在 [subshel​​l](https://www.tldp.org/LDP/abs/html/subshel​​ls.html) 中运行 grep) 。cincodenada 的答案中的技巧也会起作用。 (4认同)
  • 整洁的。短的。优雅的。当管道输入 grep 时有没有办法让它工作? (3认同)
  • 不适用于set -e.请看我的答案. (2认同)

cin*_*ada 11

我遇到了这个,需要一个onlyifPuppet声明.因此,Tgr的bash解决方案不起作用,我不想像Christopher Neylan的回答那样扩大复杂性.

我最终使用的是受HenriSchomäcker的答案启发的版本,但显着简化:

grep -P "STATUS: (?!Perfect)" recess.txt; test $? -eq 1
Run Code Online (Sandbox Code Playgroud)

这非常简单地反转退出代码,只有在找不到文本时才返回成功:

  • 如果grep返回0(找到匹配),test 0 -eq 1则返回1.
  • 如果grep返回1(未找到匹配项),test 1 -eq 1则返回0.
  • 如果grep返回2(错误),test 2 -eq 1将返回1.

这正是我想要的:如果找不到匹配则返回0,否则返回1.


Rob*_*l86 8

为了使它能够set -e在子shell中使用(和包围它):

$ cat test.sh 
#!/bin/bash

set -ex
(! ls /tmp/dne)
echo Success
$ ./test.sh 
+ ls /tmp/dne
ls: cannot access /tmp/dne: No such file or directory
+ echo Success
Success
$ mkdir /tmp/dne
$ ./test.sh 
+ ls /tmp/dne
$ 
Run Code Online (Sandbox Code Playgroud)


Chr*_*lan 6

实际上你根本不需要使用它exit.从逻辑上讲,无论grep的结果是什么,你的脚本都会退出.由于shell脚本的退出值是运行的最后一个命令的退出代码,因此只需grep运行最后一个命令,使用-v选项反转匹配以更正退出值.因此,您的脚本可以简化为:

grep -vqP "STATUS: (?!Perfect)" recess.txt
Run Code Online (Sandbox Code Playgroud)

编辑:

抱歉,当文件中有其他类型的行时,上述操作无效.为了避免运行多个命令,awk可以通过以下方式完成整个shebang:

awk '/STATUS: / && ! /Perfect/{exit 1}' recess.txt
Run Code Online (Sandbox Code Playgroud)

如果您决定要grep提供的输出,您可以执行以下操作:

awk '/^STATUS: / && ! /Perfect/{print;ec=1} END{exit ec}' recess.txt
Run Code Online (Sandbox Code Playgroud)


Eri*_*uff 5

仅否定返回值在 set -e 上下文中不起作用。但你可以这样做:

! grep -P "STATUS: (?!Perfect)" recess.txt || false
Run Code Online (Sandbox Code Playgroud)


gcb*_*gcb 5

如果有人到这里寻找bash返回代码操作:

(grep <search> <files> || exit 0 && exit 123;)
Run Code Online (Sandbox Code Playgroud)

0当grep找不到任何东西时,这将返回(成功),123当它发生时返回(失败).括号是以防任何人在shell提示符下测试它.使用括号,它不会在退出时注销,而只是使用相同的错误代码退出子shell.

我用它来快速检查js文件:

find src/js/ -name \*js -exec node \{\} \; 2>&1 | grep -B 5 SyntaxError || exit 0 && exit 1;
Run Code Online (Sandbox Code Playgroud)