パイプを通してgrep -vで探す

パイプを通してgrep -vで探す

特定の文字列を含まない特定の種類のすべてのファイルを見つけようとします。 grep -vにfindを接続してこの問題を解決しようとしています。

例:

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

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

私が何か間違っていると思います。それでは、命令はどのようなものでなければなりませんか?

答え1

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

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

答え2

あなたは本当に得ようとしています...

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

ここから始めるには「.」をクリックしてください。 (あなたは暗示していますが、決して仮定しません)。

-私の名前場合に備えて大文字と小文字を区別しない検索を使用してください。
-0を印刷してください。ファイル名を後ろに \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" *

すべてを検索するためにもっと多くのことを行いますが、いくつかの結果を提供する必要があります。

答え3

コンピュータはコンピュータです。コンピュータは、ユーザーが望むように実行するのではなく、ユーザーが指示したとおりに実行します。

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…

-L一部のgrepバージョンにはこのオプションはありません。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

答え4

find -type f -name '*.java' 2>&1 | grep -v "something something"

「grepping out」した内容は stdout ではなく stderr に表示されます。

上記のコマンドは、stderrをstdoutにリダイレクトします。

源泉

関連情報