検索をgrep -vにパイプする


18

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

例:

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

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

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


うまくいかなかったと思わせるものを追加するかもしれません。多分あなたのgrep式はあまりにも明示的ですか?大文字と小文字を区別しないために「-i」が必要ですか?以下の私の回答も参照してください...
lornix

回答:


20

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

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

1
-Lを意味するので、すでに交渉していますfiles _without_ match。したがって、-vここでオプションは必要ありません。
ラッシュ

3
最後に余分な+を付けないでください。
lynxlynxlynx

2
@ user946850を書くたびfind -exec \+に、xargsを使用する方がずっと良いと書いてくれます。コメントを書く前に誰も男に見えないのはなぜですか?(:
急ぎます

5
@ user946850はと-exec ... {} \+同等ではありませんxargs。findutilsのドキュメントをお読みください!(私はそれに一生懸命取り組みました!)
ジェームズヤングマン

2
@ user946850はい。違いの1つは、(デフォルトで)xargs入力を処理し、空白で引数を分離することです。引用符も(デフォルトで)特別ですxargs。これらのことのどちらも当てはまりません-exec ... {} +。以前のバージョンではxargs、アンダースコアをEOFインジケーターと見なしていましたが、これは事実ではありません。
ジェームズヤングマン

7

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

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

ドット「。」ここから始めるように言っています。(あなたのものはそれを意味します。

-inameは、大文字と小文字を区別しない(または大文字と小文字を区別しない)大文字と小文字を区別しない検索を使用します。
-print0は、末尾に\ 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" *

すべてを検索するためにより多くの作業を行いますが、出力が得られるはずです。


私はあなたの変更を試みましたが、まだ期待した結果が得られません。質問をより明確にするために更新してみます。
ヒアンジェロ

質問の作成者がファイル名だけを検索したい場合、grepを 'grep -l -v'にしないでください。
ブルースエディガー

彼は* .javaファイルの特定のコンテンツを探しています
-lornix

xargs -0 grep -v "something something"あるべきxargs -0 grep -v "something something" /dev/null発見は、一致するファイルを生成しないときにそうあなたは奇妙な結果が得られます。
ジェームズヤングマン

{Grin}ええ、どこかでロジックが毛むくじゃらになりました。あなたの頭を傷つける逆偽論理の複数のテストのようなものはありません。
lornix

4

コンピューターはコンピューターです。それは、あなたがやりたいことではなく、あなたが指示したことをしています。

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

うわーこれはさらに良いです。私は、「extends(/ s)+ SomethingSomething」を使用していました。この構文とExtended RegExバージョンで指定された構文に違いはありますか?
ヒアンジェロ

@Hyangelo \sはGNU grep拡張機能で、これはと同義だと思います[[:space:]]
ジル「SO-悪であるのをやめる」
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.