'grep -c'を折りたたむ方法*.h *.cpp'を単一のカウントに変換しますか?

'grep -c'を折りたたむ方法*.h *.cpp'を単一のカウントに変換しますか?

NDEBUGPosixアサーションの依存関係が存在しないことを確認するために、C ++コードに独自のテストを追加しています(後述)。最初のテストでは、<assert.h>次の合計を見つけます<cassert>

FAILED=0
COUNT=$($EGREP -c '(assert.h|cassert)' *.h *.cpp)
if [[ "$COUNT" -ne "0" ]]; then
    FAILED=1
    echo "Found Posix assert headers" | tee -a "$TEST_RESULTS"
fi

生産:

************************************
Testing: No Posix assert

./cryptest.sh: line 1130: [[: 3way: value too great for base (error token is "3way")
...

デバッグすると、次のように表示されます。

bash -x ./cryptest.sh
...

++ egrep -c '(assert.h|cassert)' 3way.h adler32.h aes.h ...
+ COUNT='3way.h:0
adler32.h:0
aes.h:0
...

したがって、各ファイルには独自の行と数があります。

これgrepマニュアルページステートメントは次のとおりです。複数行出力については議論しません。

-c, --count
    Only a count of selected lines is written to standard output.

この行動は以下に関連しているようです。出力制御(マンページ構成)と-l, --files-with-matches-L, --files-without-match同様のエラーが発生します。

私の質問は、結果をどのようにgrep組み合わせることができるかということです。

それとも、grepとegrepがそのタスクに適したツールであるかどうか尋ねるべきですか? grepとegrepが正しいツールではない場合、何を使うべきですか?


これは、私たちがサポートするすべてのプラットフォームで実行できるBashシェルスクリプトです。各プラットフォームには、BSD、Linux、OS X、Solaris、およびUnix(AndroidやiOSなどのすべてのモバイルバージョンを含む)が含まれています。私たちは、grep次のような必要なツールを得るために一生懸命努力する必要がありますegrep

GREP=grep
EGREP=egrep
SED=sed
AWK=awk
DISASS=objdump
DISASSARGS=("--disassemble")
...

# Fixup
if [[ "$IS_SOLARIS" -ne "0" ]]; then
    IS_X64=$(isainfo 2>/dev/null | "$GREP" -i -c "amd64")
    if [[ "$IS_X64" -ne "0" ]]; then
        IS_X86=0
    fi

    # Need something more powerful than the non-Posix versions
    if [[ (-e "/usr/gnu/bin/grep") ]]; then
        GREP=/usr/gnu/bin/grep;
    fi
    if [[ (-e "/usr/gnu/bin/egrep") ]]; then
        EGREP=/usr/gnu/bin/egrep;
    fi
    if [[ (-e "/usr/gnu/bin/sed") ]]; then
        SED=/usr/gnu/bin/sed;
    fi
    if [[ (-e "/usr/gnu/bin/awk") ]]; then
        AWK=/usr/gnu/bin/awk;
    else
        AWK=nawk;
    fi

    DISASS=dis
    DISASSARGS=()
fi

...

背景ストーリー

私たちのプロジェクトは最近CVE-2016-7420これは、AutotoolsやCMakeなどの他のツールを使用してプロジェクトを構築するためです。 CVEは、-DNDEBUGリリース/本番ビルドの省略の直接的な結果です。他のツールは私たちとは異なるように構成されており、ユーザーに(1)他のビルドツールを使用できないか(2)ユーザーに通知しません。〜しなければならない-DNDEBUGリリース/プロダクションを定義します。

私たちの救済策NDEBUGドキュメントで「単にリリース/プロダクションを定義する」よりもはるかに深いです。私たちはNDEBUGPosixへのすべての依存関係を削除します。assertしたがって、人々が誤って構成に入ることはできません。また、ユーザーはDEBUG定義してデバッグ構成を要求する必要があります_DEBUG。それ以外の場合は、リリース設定を受け取ります。

後者assertSIGART通常リリースビルドでは面倒ですが、デバッグビルドではポジティブと見なされ、当然と見なされますが、私たちは以下を観察しました。

  • 私たちは安全な図書館です(機密情報を処理します)
  • 失敗したアサーションは、重要な情報をファイルシステム(コアファイルと競合レポート)に渡します。
  • 失敗したアサーションは、Apple(CrashReporter)、Apport(Ubuntu)、Microsoft(Windows Error Reporting)などのプラットフォームベンダーに重要な情報を漏洩します。
  • Apple、Google、Microsoftなどの企業は政府と協力して機密情報を収集します。

答え1

注:以下はGNUの実装に基づいていますgrepが、あなたの場合でもうまくいくと思います。

GNUのgrepマニュアルに記載されているように(強調)

grep searches the named input FILEs for lines containing a match to the
given PATTERN.  If no files are specified, or if the file “-” is given,
grep  searches  standard  input.   By default, grep prints the matching
lines.

返品、

-c, --count
       Suppress  normal output; instead print a count of matching lines
       **for each input file**.  With the -v,  --invert-match  option  (see
       below), count non-matching lines.

(デフォルトの動作は、その出力でファイル名の前にプレフィックスを付けることです。ただし、-hこのオプションを使用するとこれを抑制できます。)

ターゲットファイルを単一の入力ストリームに接続し、次にパイプして両方の動作をgrepオーバーライドし、プレフィックスなしで単一の数を取得できる必要があります。

COUNT=$(cat *.h *.cpp | $EGREP -c '(assert.h|cassert)')

IMHO これは以下の資格があります。効果がある猫を使ってください。おそらくあなたが推奨するもの猫の無駄な使用

答え2

スチールドライバーの回答あなたの質問のタイトルを読んだとき(do)という考えが最初に聞きました。しかし、スクリプトフラグメントでゼロと比較する以外は、カウントを使用しないことがわかりました。つまり、「何個ありますか?」と聞いているのです。以下を使用することを検討してください。cat files | grep -c <token>-q

if "$EGREP" -q -- 'assert\.h|cassert' *.h *.cpp
then
    FAILED=1
    echo "Found Posix assert headers" …
fi

メモ:

  • "$EGREP"妥当な理由がなく、実行している操作がわからない限り、常にシェル変数参照(例:)を引用する必要があります。定義した場合、EGREP=grep -eこれはquoteを使用しない妥当な理由になります$EGREP。ただし、以下を参照してください。この回答到着bash / POSIXシェルで変数を引用することを忘れてしまうセキュリティリスク
  • -q(または同等に--quietor --silent)は、「静かです。標準出力に何も書き込まないでください。一致するものが見つかった場合は、エラーが検出された場合でもステータス0で直ちに終了してください。」を意味します。これは、必要な機能的動作(つまり、Steeldriverの答えと同じ機能的動作ですが、一致が見つかったら終了し、すべてのgrepファイルを読む必要がないというパフォーマンス上の利点があります。 
  • で始まるファイル名がオプション文字列として解釈されるのを--防ぐために、コマンドのオプションとその引数の間に配置することをお勧めします。-
  • 正規表現全体を括弧で囲む必要はありません。
  • grep 'assert.h'assert h、、、assert,hなどと一致しますassert3hassertphあなたが気にしない場合は、それに依存します。ただ一致させるにはassert.hgrep for assert\.h.

関連情報