Подтвердить что ты не робот

Bash: однострочный выход для выхода с противоположным статусом команды grep?

Как я могу уменьшить следующие bash script?

grep -P "STATUS: (?!Perfect)" recess.txt && exit 1
exit 0

Кажется, что я могу сделать это с помощью одной команды, но у меня здесь всего 3.

Моя программа должна:

  • Прочитайте файл recess.txt
  • Выход 1 (или ненулевой), если он содержит строку с "STATUS:" NOT "Perfect"
  • Выход 0, если такая строка не существует (т.е. все строки "STATUS:" "Perfect" )

Ответ на награду распространяется на самый жесткий script. Спасибо!

Примеры файлов

Программа должна иметь статус выхода 0 для этого файла:

FILE: styles.css 
STATUS: Perfect!

FILE: contour-styles.css
STATUS: Perfect!

Программа должна иметь статус выхода 1 (или ненулевой) для этого файла:

FILE: styles.css 
STATUS: Perfect!

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

Id should not be styled
       1. #asdf
4b9b3361

Ответ 1

Просто отрицать возвращаемое значение.

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

Ответ 2

Я наткнулся на это, требуя инструкции onlyif для Puppet. Таким образом, Tgr bash solution не будет работать, и я не хотел бы расширять сложность, как в Christopher Ответ Нейлана.

В итоге я использовал версию, вдохновленную ответом Анри Шомэкера, но заметно упрощенное:

grep -P "STATUS: (?!Perfect)" recess.txt; test $? -eq 1

Что очень просто инвертирует код выхода, возвращая успех, только если текст не найден:

  • Если grep возвращает 0 (найдено совпадение), test 0 -eq 1 вернет 1.
  • Если grep возвращает 1 (совпадение не найдено), test 1 -eq 1 вернет 0.
  • Если grep возвращает 2 (ошибка), test 2 -eq 1 вернет 1.

Это именно то, что я хотел: return 0, если совпадение не найдено, и 1 в противном случае.

Ответ 3

Вам вообще не нужно использовать exit. Логически, независимо от результата grep, ваш script все равно выйдет. Поскольку значение выхода оболочки script является кодом завершения последней команды, которая была запущена, просто запустите grep как последнюю команду, используя опцию -v, чтобы инвертировать совпадение для коррекции значения выхода. Таким образом, ваш script может свести к следующему:

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

EDIT:

Извините, это не работает, если в файле есть другие типы строк. В интересах избежания выполнения нескольких команд, однако, awk может выполнить весь shebang с чем-то вроде:

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

Если вы решите, что хотите получить данные, которые grep предоставил, вы можете сделать:

awk '/^STATUS: / && ! /Perfect/{print;ec=1} END{exit ec}' recess.txt

Ответ 4

Чтобы он работал с set -e, окружайте его в суб-оболочке с помощью ( и ):

$ 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
$ 

Ответ 5

Просто отрицание возвращаемого значения не работает в контексте set -e. Но вы можете сделать:

! grep -P "STATUS: (?!Perfect)" recess.txt || false

Ответ 6

если кто-то получает здесь поиск bash манипуляции с кодом возврата:

(grep <search> <files> || exit 0 && exit 123;)

это вернет 0 (успех), когда grep ничего не обнаружит, и верните 123 (отказ), когда это произойдет. Скобки заключаются в том случае, если кто-либо проверит ее так же, как и в командной строке. с круглой скобкой он не выйдет из системы на выходе, а просто выйдет из подоболочки с тем же кодом ошибки.

Я использую его для быстрой проверки синтаксиса в файлах js:

find src/js/ -name \*js -exec node \{\} \; 2>&1 | grep -B 5 SyntaxError || exit 0 && exit 1;

Ответ 7

Используйте специальную переменную ?:

grep -P "STATUS: (?!Perfect)" recess.txt
exit $((1-$?))

(Но обратите внимание, что grep также может возвращать 2, поэтому не ясно, что вы хотите встретить в таких случаях.)

Ответ 8

Проблема с ответами grep заключается в том, что если файл пуст, вы также получаете чистый ответ, как если бы файл был совершенным. Поэтому лично я отказался от grep для этого и использовал 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

Ответ 9

[ $(grep -c -P "STATUS: (?!Perfect)" recess.txt) -eq 0 ]

Ответ 10

Мне также понадобилось такое решение для написания марионетки только в том случае, если было сделано выражение, и придумал следующую команду:

/bin/grep --quiet 'root: [email protected]' /etc/aliases; if [ $? -eq 0 ]; then test 1 -eq 2; else test 1 -eq 1; fi;