我有大約 500 個字串,我想在目錄中搜尋包含它們的檔案並獲取包含這些字串的檔案名稱。到目前為止我一直在使用:
find -name 'LYFNRE.*' -exec grep -f file1.txt {} \; -print
但問題是一個字串可以在許多文件中找到,因此由於輸出巨大,很難找到哪些字串存在以及哪些字串丟失。您能幫我列印字串以及找到它們的相應檔案名稱嗎?
答案1
你應該只grep
給你文件名。 GNUgrep
可以做到這一點:
grep -HFf ../strings.txt *
這將為您提供以下輸出:
[filename]:[matched_line]
...目錄中每個檔案的每個符合項目。您還可以獲得行號:
grep -HnFf ../strings.txt *
....這提供了...
[filename]:[line_number]:[matched_line]
答案2
問題是您一次將一個文件傳遞到grep
.當grep
在命令列上看到單個檔案時,它會假設您確切知道要搜尋的位置,因此它不會在匹配項前面顯示檔案名稱。
強制grep
始終輸出檔案名稱的一個技巧是也通過/dev/null
(永遠不會有任何匹配)。一些 grep 實作有一個選項:-H
。
此外,您可以使用-exec … {} +
而不是-exec … {} \;
一次性執行多個文件的程式。這更快。您仍然應該傳遞/dev/null
or -H
,因為可能會發生只對一個文件調用該命令的情況,要么是因為只有一個匹配文件,要么是因為有許多匹配項需要grep
多次調用,而其中一次恰好涉及單個文件。
find -name 'LYFNRE.*' -exec grep -f file1.txt /dev/null {} +
GNU grep 和最近的 BSD 實作(包括 OSX)支援遞歸grep
呼叫而不需要find
.
grep -R --include='LYFNRE.*' -f file1.txt -H .
或者,您可以在 shell 中進行遞歸通配。在 zsh 中,這是開箱即用的。在 bash 中,您需要shopt -s globstar
先執行,並注意 bash 透過目錄的符號連結進行遞歸(與find
或 zsh 不同)。
grep -f file1.txt /dev/null **/LYFNRE.*
答案3
使用egrep:
egrep -n "str1|str2|str3" file_names
-n 將列印找到字串的特定檔案中的行號