次のbashスクリプトを削減するにはどうすればよいですか?
grep -P "STATUS: (?!Perfect)" recess.txt && exit 1
exit 0
たった1つのコマンドでできるはずですが、ここでは合計3つです。
私のプログラムは:
回答賞は最も厳しいスクリプトに与えられます。ありがとう!
このファイルのプログラムにはexit statusが必要です:
FILE: styles.css
STATUS: Perfect!
FILE: contour-styles.css
STATUS: Perfect!
プログラムには、このファイルに対してexit status 1(または0以外)が必要です。
FILE: styles.css
STATUS: Perfect!
FILE: contour-styles.css
STATUS: Busted
FAILURES: 1 failure
Id's should not be styled
1. #asdf
ただ negate 戻り値。
! grep -P "STATUS: (?!Perfect)" recess.txt
私はこれに遭遇し、Puppetにonlyif
ステートメントが必要でした。そのため、 Tgrのbashソリューション は機能せず、 Christopher Neylanの回答 のように複雑さを拡張したくありませんでした。
私は HenriSchomäckerの答え に触発されたバージョンを使用することになりましたが、特に単純化されました。
grep -P "STATUS: (?!Perfect)" recess.txt; test $? -eq 1
これは非常に単純に終了コードを反転し、テキストが見つからない場合にのみ成功を返します。
test 0 -eq 1
は1を返します。test 1 -eq 1
は0を返します。test 2 -eq 1
は1を返します。これはまさに私が欲しかったものです。一致が見つからない場合は0を返し、そうでない場合は1を返します。
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
$
実際には、exit
を使用する必要はまったくありません。論理的には、grepの結果に関係なく、スクリプトはとにかく終了します。シェルスクリプトの終了値は最後に実行されたコマンドの終了コードなので、-v
オプションを使用してgrep
runを最後のコマンドとして実行し、一致を反転させて終了を修正します値。したがって、スクリプトは次のように削減できます。
grep -vqP "STATUS: (?!Perfect)" recess.txt
編集:
ファイルに他のタイプの行がある場合、上記は機能しません。ただし、複数のコマンドを実行しないようにするために、awk
は次のような方法でシバン全体を実行できます。
awk '/STATUS: / && ! /Perfect/{exit 1}' recess.txt
Grepが提供するはずの出力が必要であると判断した場合は、次のようにすることができます。
awk '/^STATUS: / && ! /Perfect/{print;ec=1} END{exit ec}' recess.txt
誰かがbashの戻りコード操作を探してここに来た場合:
(grep <search> <files> || exit 0 && exit 123;)
これにより、grepで何も見つからなかった場合は0
(成功)が返され、見つかった場合は123
(失敗)が返されます。括弧は、シェルプロンプトでそのままテストする場合に使用します。括弧を付けると、終了時にログアウトせず、同じエラーコードでサブシェルを終了します。
私はそれをjsファイルの簡単な構文チェックに使用します:
find src/js/ -name \*js -exec node \{\} \; 2>&1 | grep -B 5 SyntaxError || exit 0 && exit 1;
戻り値を否定するだけでは、set -eコンテキストでは機能しません。しかし、あなたはできる:
! grep -P "STATUS: (?!Perfect)" recess.txt || false
特別な?
変数 :
grep -P "STATUS: (?!Perfect)" recess.txt
exit $((1-$?))
(ただし、grep
も2を返す可能性があるため、このような場合に何を実行するかは明確ではありません。)
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
[ $(grep -c -P "STATUS: (?!Perfect)" recess.txt) -eq 0 ]
私はまた、ステートメントをifし、次のコマンドを考え出した場合にのみ人形を書くためのそのような解決策を必要としました:
/bin/grep --quiet 'root: [email protected]' /etc/aliases; if [ $? -eq 0 ]; then test 1 -eq 2; else test 1 -eq 1; fi;