web-dev-qa-db-ja.com

パイプ検索をgrep -vに

特定のタイプで特定の文字列を含まないすべてのファイルを検索しようとしています。 findをgrep -vにパイプすることでそれを回避しようとしています

例:

find -type f -name '*.Java' | xargs grep -v "something something"

これは機能していないようです。 findコマンドが見つけたすべてのファイルを返すだけのようです。私がやろうとしていることは、基本的に、特定のファイル名に一致する(たとえば、SessionPb.Javaのように「Pb」で終わる)すべての.Javaファイルを見つけ、その中に「extends SomethingSomething」がないことです。

私の疑いは、私がそれを間違っていることです。では、コマンドはどのように見えるべきでしょうか?

19
Hyangelo

ここではxargsは必要ありません。また、grep-Lオプション(一致しないファイル)とともに使用する必要があります。そうしないと、例のように、名前ではなくファイルの内容が出力されます。

find . -type f -iname "*.Java" -exec grep -L "something somethin" {} \+
22
rush

あなたはほとんどそれを本当に持っています...

find . -type f -iname "*.Java" -print0 | xargs -0 grep -v "something something"

ドット「。」ここから始めると言います(あなたはそれを暗示する..しかし決して想定しない)。

-inameは、大文字と小文字を区別しない検索を使用します(大文字と小文字の区別なし)。
-printは、末尾に\ x00文字を付けてファイル名をxargsに送信します。これにより、ファイル名にスペースが含まれている場合の問題が回避されます。

xargsの '-0'は、ファイル名が\ x00で終わるのではなく、リターンを期待することを示しています。

そしてあなたのgrepコマンド...

かなりそれを得た。


編集::

更新から:

find . -type f -iname "*pb.Java" -print0 | xargs -0 grep -iL "something"

役立つはずです。 (@Rushの回答から-Lを追加、よくできました)

あなたのgrepは '-i'オプションを必要とするか、それほど明示的でないことが必要だと思います。

コマンドを部分的に試してみてください...このファイル名は適切と思われますか?

find . -type f -iname "*pb.Java"

もしそうなら、あなたの問題はおそらくあなたのgrep検索パターンが一致していない(スペルエラー?それが起こります!)か、一致がまったくないかのどちらかです。

絶対最悪の場合:

grep -riL "something" *

すべてを検索する多くの作業を行いますが、いくつかの出力が表示されます。

7
lornix

コンピューターはコンピューターです。コンピューターは、ユーザーが望んでいたことの代わりに、ユーザーが指示したことを実行しています。

grep -v "something something"は、something somethingを含まないすべての行を出力します。たとえば、次の3つのうち2行を出力します。

hello world
this is something something
something else

extends SomethingSomethingを含まないファイルを印刷するには、-Lオプションを使用します。

grep -L -E 'extends[[:space:]]+SomethingSomething' FILENAME…

Grepの一部のバージョンには-Lオプションがありません(これは [〜#〜] posix [〜#〜] で指定されていません)。表示されない場合は、何も出力せず、戻りコードを使用して、呼び出し側のシェルに代わりに何をすべきかを実行させます。

grep -q -E 'extends[[:space:]]+SomethingSomething' FILENAME ||
echo "$FILENAME"

または、awkを使用します。

awk '
    FNR == 1 && NR != 1 && !found { print fn }
    FNR == 1 { fn = FILENAME; found = 0; }
    /extends[[:space:]]+SomethingSomething/ { found = 1 }
    END { if (fn != "" && !found) print fn }
'

LinuxまたはCygwin(またはGNU grep)を備えた他のシステム)では、findは再帰可能であるため、grepを使用する必要はありません。

grep -R --include='*.Java' -L -E 'extends[[:space:]]+SomethingSomething'

シェルがksh、bash、またはzshの場合、シェルにファイル名のマッチングを実行させることができます。 bashでは、最初にset -o globstarを実行します(これを~/.bashrcに入れることができます)。

grep -L -E 'extends[[:space:]]+SomethingSomething' **/*.Java