如何循環遍歷目前目錄和子目錄中的所有檔案來尋找字串?

如何循環遍歷目前目錄和子目錄中的所有檔案來尋找字串?

您好,例如,我試圖循環遍歷目錄及其所有子目錄以在所有文件中查找字串“foo”。然後我想顯示包含它的所有檔案的檔案名稱(包括完整路徑)。

作業系統是unix並使用bash shell。

任何建議,將不勝感激。謝謝

答案1

您可以使用遞迴grepgrep至少在 GNU 中,這是一個-R選項:

grep -R foo /path/to/parent/directory

例如,如果您使用完整路徑(如上所述),/home/callsign223/foo/則所有文件都將顯示其合格路徑。如果您只想查看文件名,而不是匹配的行,則可以使用-l僅列印文件名:

grep -lR foo /path/to/parent/directory

請注意,該選項不可移植,並且並非所有實作-R都支援。grep

答案2

如果grep -R不是一個選項,那麼您可以使用在每個文件上find運行:grep

find ./ -type f -exec grep -Hni "some-string" {} ';'

答案3

適用於所有目前 Unix 系統的方法是使用find查找文件,然後grep識別包含字串 的文件foo

find . -type f -exec grep -l -F -e 'foo' {} +

上面的命令將查找當前目錄中或當前目錄下的所有常規檔案。對於批次找到的文件,grep將呼叫 來定位字串foo。在文件中尋找字串時,grep立即輸出文件的路徑名並繼續下一個文件,而不進一步讀取目前文件。

  • 我們用來-l停止grep並在與給定模式匹配的第一行報告檔案名稱。這可以透過忽略第一次命中後的檔案位元來加快處理速度。
  • 我們通常-Fgrep模式視為字串而不是正規表示式。這可能會透過不嘗試去正規表示式匹配來加快處理速度,並允許我們匹配看起來像正規表示式的字串。
  • 我們使用-e給定的模式,以防萬一它以破折號開頭。在本例中它不會這樣做,但是foo用變數替換該靜態字串會引入與以破折號開頭的模式匹配的可能性,因此,這會被誤認為是命令列選項。

不過,檔案名稱列表通常沒什麼好處。您可能想要對這些文件執行某些操作。如果是這樣,您可以將其作為find透過以下方式執行的實用程式的一部分來執行-exec

find . -type f -exec sh -c '
    for pathname do
        grep -q -F -e "foo" "$pathname" || continue
        # Do something with "$pathname" here
    done' sh {} +

這裡我們呼叫一個簡短的內聯腳本來批次處理找到的檔案。我們單獨檢查每個文件中的字串foo,並忽略不包含該字串的文件。我在內聯腳本中添加了註釋,您將處理"$pathname".

您也可以在呼叫內聯腳本之前單獨find執行上面的程式碼:grep

find . -type f -exec grep -q -F -e 'foo' {} \; -exec sh -c '
    for pathname do
        # Do something with "$pathname" here
    done' sh {} +

請注意第一個如何在調用通過該測試的文件-exec之前對當前文件進行測試。sh -c

答案4

我相信該ack實用程式將完全滿足您的需求。它可能已經安裝在您的系統上。如果沒有的話可以從以下網址下載https://beyondgrep.com/

的一個很好的功能ack是它默認忽略二進位文件,並且可以給定命令行選項來限制通過某些指定的過濾器或文件類型搜索的文件類型(例如通過編程語言:將--type=cc搜索.c,,文件,將搜索第一行中匹配的任何文件)。使用者還可以在命令列上或更永久地在檔案中擴展這些類型。.h.xs--type=awk/awk/~/.ackrc

相關內容