44

次のbashスクリプトを減らすにはどうすればよいですか?

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

1つのコマンドで実行できるはずですが、ここには合計3つあります。

私のプログラムは:

  • Recess.txtを読む
  • 「パーフェクト」ではない「ステータス:」の行が含まれている場合は、1(またはゼロ以外)を終了します。
  • そのような行が存在しない場合は0を終了します(つまり、すべての「ステータス:」行は「パーフェクト」です)

答えの賞は最も厳しいスクリプトに行きます。ありがとう!

サンプルファイル

このファイルのプログラムの終了ステータスは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's should not be styled
       1. #asdf
4

11 に答える 11

54

戻り値を否定するだけです。

! grep -P "STATUS: (?!Perfect)" recess.txt
于 2014-02-14T20:08:37.130 に答える
17

私はこれに出くわし、onlyifPuppet のステートメントが必要でした。そのため、Tgr の bash ソリューションは機能せず、 Christopher Neylan の answer のように複雑さを拡大したくありませんでした。

Henri Schomäcker's answerに触発されたバージョンを使用することになりましたが、特に単純化されています。

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 11 を返します。

これはまさに私が望んでいたものです: 一致が見つからない場合は 0 を返し、それ以外の場合は 1 を返します。

于 2015-05-28T00:27:02.190 に答える
10

サブシェルでandで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
$ 
于 2015-07-21T21:26:46.737 に答える
9

誰かがここに来て、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;
于 2016-02-02T23:50:37.853 に答える
5

set -e コンテキストでは、戻り値を否定するだけでは機能しません。しかし、次のことができます。

! grep -P "STATUS: (?!Perfect)" recess.txt || false
于 2015-06-29T23:20:58.520 に答える
5

実際にはまったく使用する必要はありませんexit。論理的には、grep の結果がどうであれ、スクリプトはとにかく終了します。シェル スクリプトの終了値は実行された最後のコマンドの終了コードであるため、一致を反転して終了値を修正するオプションをgrep使用して、最後のコマンドとして実行しただけです。-vしたがって、スクリプトは次のように削減できます。

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
于 2013-03-12T17:31:26.320 に答える
1

特別な?変数を使用します:

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

(ただし、grepが 2 を返すこともあるため、そのような場合に何が発生するかは明確ではありません。)

于 2013-03-12T17:12:33.357 に答える
1

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
于 2015-11-12T10:02:26.167 に答える
0

また、ステートメントのみのパペットを作成するためのそのようなソリューションが必要であり、次のコマンドを思いつきました。

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

于 2014-12-04T09:20:17.423 に答える