我正在嘗試查找特定類型且不包含特定字串的所有文件。我正在嘗試通過管道 find 到 grep -v 來解決這個問題
例子:
find -type f -name '*.java' | xargs grep -v "something something"
這似乎不起作用。它似乎只是返回 find 命令找到的所有檔案。我想做的基本上是找到與某個檔案名稱相符的所有 .java 檔案(例如,以 SessionPb.java 中的“Pb”結尾)並且內部沒有“extends SomethingSomething”。
我懷疑我做錯了。那麼該命令應該是什麼樣子呢?
答案1
這裡沒有必要xargs
。此外,您還需要使用grep
with-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將檔案名稱傳送到 xargs 並帶有尾隨 \x00 字符,這可以防止檔案名稱中包含空格的問題。
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
。例如,它會列印以下三行中的兩行:
hello world
this is something something
something else
若要列印不包含extends SomethingSomething
任何內容的文件,請使用以下-L
選項:
grep -L -E 'extends[[:space:]]+SomethingSomething' FILENAME…
某些版本的 grep 沒有該-L
選項(它不是由POSIX)。如果您的 shell 不這樣做,請讓它不列印任何內容,並使用返回程式碼讓呼叫 shell 執行它應該執行的操作。
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'
如果您的 shell 是 ksh、bash 或 zsh,您可以讓 shell 進行檔案名稱匹配。在 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」的內容顯示到stderr,而不是stdout。
上面的指令將 stderr 重新導向到 stdout