我正在查找包含“AAA”和“BBB”的目錄中的所有檔案。然后我想對每個找到的檔案進行修改/處理。檔案名確實包含空格。
grep管道grep似乎很簡單,但需要xargs正確運行。
grep(據我所知)中的多重匹配功能僅適用于“AAA”或“BBB”。
我所擁有的是:
for FILENAME in "$(grep -ilrZ "AAA" ./files/* | xargs -0 grep -ilr "BBB")"
do
echo "$FILENAME"
echo "match"
done
但是,這會將串列視為檔案(包括換行符)作為單個物體(即“匹配”只會列印一次)。
從for子外殼中洗掉雙引號意味著每個空格都是要回圈的新事物,這會破壞檔案名。
uj5u.com熱心網友回復:
您grep -Z在第一次呼叫中的使用也是第二種情況下問題的解決方案。
grep -ilrZ "AAA" ./files/* |
xargs -r0 grep -Zil "BBB" |
xargs -r0 -i echo "{} match"
-r在第二個中使用grep沒有意義,因為您只想精確檢查第一個輸出中的檔案grep。
如果您只想列出檔案,當然,grep -l已經這樣做了;大概,你會想要在第二個中做一些更復雜的事情xargs。
另一種解決方案可能是
find ./files -type f \
-exec grep -qi "AAA" {} \; \
-exec grep -qi "BBB" {} \; \
-exec sh -c 'for f; do echo "$f matced"; done' _ {}
其作業方式是,如果-exec失敗,則失敗的檔案將被 視為失敗的謂詞find,因此將跳過其余的謂詞。到達最終謂詞的檔案將從所有先前的謂詞回傳成功。
grep -Z后者應該在缺少 GNU 擴展等的非 Linux 平臺上作業xargs -0。
如果它不明顯,find也grep -r檢查子目錄。如果您只想檢查當前目錄,-r則從第一個目錄中省略grep應該可以。對于find,您可以添加-maxdepth 1before-type f以僅檢查當前目錄。
演示:https ://ideone.com/ELqKxZ
有關此主題的更多資訊,另請參閱https://mywiki.wooledge.org/BashFAQ/020和https://mywiki.wooledge.org/DontReadLinesWithFor
uj5u.com熱心網友回復:
@tripleee 有一個出色而可靠的答案。另一種選擇。假設你的 shell 是 bash 而你的 awk 是 GNU awk
shopt -s globstar # enable recursive globbing with **
gawk '
BEGINFILE {a = b = 0}
/AAA/ {a = 1}
/BBB/ {b = 1}
a && b {print FILENAME; nextfile}
' ./files/** 2>/dev/null
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/470668.html
