我在使用 .一次搜尋所有目錄時遇到問題grep
。當我使用命令時:
find . -name "*.txt" | xargs grep texthere
它只是需要很長時間,然後給我“沒有這樣的文件或目錄”錯誤。
為什麼會發生這種情況,還有什麼比這更簡單的事嗎grep
?或者我使用了錯誤的命令?
答案1
如果您有 GNU grep,則 grep 本身支援“-r”選項來遞歸搜索,如 @Ouroborus 所建議的。
如果不幸的是你的 grep 不支援這樣的選項,例如在 SunOS 中,你可以使用以下命令:
find . -name "*.txt" -exec grep -n your_pattern {} /dev/null \;
新增技巧是/dev/null
為了確保每次執行 grep 時都提供兩個檔案(符合 *.txt 的檔案和 /dev/null),強制它列印正在搜尋的檔案的名稱。您可以新增-type f
選項來find
細化 的範圍find
。
答案2
如在這個答案,你可能會更好:
grep -rnw '/path/to/somewhere/' -e "pattern"
-r
或者-R
是遞迴的,-n
是行號,並且-w
立場與整個字相符。-l
可以添加(小寫 L)以僅給出匹配文件的文件名。
答案3
如果您收到有關權限的錯誤(您沒有說您這樣做),那麼我猜測您正站在根目錄(/
)或某個您無權讀取所有文件的路徑中,例如在/etc
或 在 中/var
。但既然你說這需要很長時間,我更傾向於第一個假設(根目錄)。
如果你想絕對搜尋全部文件在所有的系統,比你所做的非常正確。它將要無論你做什麼都要花很長時間。需要搜尋的文件數量非常多。
您可以使用find
它來縮小要查看的文件數量。
此刻,你有
$ find . -name "*.txt" | xargs grep texthere
由於您看起來只對純文字檔案感興趣,因此我們可以排除任何其他類型的檔案(可執行檔):
$ find / -type f \! -perm -o=x -name "*.txt" | xargs grep texthere
我替換.
為/
這裡,因為那是我的地方思考你是(如果我錯了請糾正我)。我還指定我想要文件( -type f
) 分別是不可執行( \! -perm -o=x
) (!
需要轉義,這樣你的 shell 就不會用它做有趣的事)。
現在,我們還有幾件事要做。一個是安全問題,一個可能是可能稍微提高速度。
某些檔案名稱中可能包含空格,或其他我們通常不希望在檔案名稱中出現的奇怪字元。為了能夠在我們find
之間正確地傳遞這些grep
$ find / -type f \! -perm -o=x -name "*.txt" -print0 | xargs -0 grep texthere
此 ( ) 表示每個檔案名稱將由字元 ( ) 而不是空格字元-print0
分隔。用於接收這些分隔檔案名稱的相應選項是.nul
\0
xargs
nul
-0
這是因為您沒有使用這兩個選項,我相信您會收到“沒有這樣的檔案或目錄”錯誤。
速度的事情是fgrep
。grep -F
如果您的搜尋字串是不含正規表示式的純文字字串,則該實用程式與您應該使用的實用程式完全相同。
因此,如果您有一個純文字字串,並且想要在整個系統上的每個文件中找到它:
$ find / -type f \! -perm -o=x -name "*.txt" -print0 | xargs -0 fgrep texthere
權限問題...顯然會有您無法讀取的檔案。您可以運行find
並fgrep
在sudo
它們前面加上:
$ sudo find ... | xargs -0 sudo fgrep texthere
或者您可以嘗試-perm
為其製作另一個標誌find
(並讓它忽略您無法輸入的目錄),但這會太耗時並導致命令行長得離譜,所以我不會在這裡這樣做。
或者你可以只是sudo -s
獲得一個 root shell 並從那裡運行這個東西......但我通常會建議不要這樣做,因為人們傾向於通過忘記他們的系統來搞亂他們的系統root
。
另一種解決方案就是使用該locate
指令來尋找.txt
整個系統上的所有檔案。該locate
命令不會搜尋檔案層次結構,而是使用資料庫(通常每天更新,因此不全部文件可能在那裡)。該資料庫僅包含所有使用者都可以存取的目錄中的文件,因此如果您刪除了自己目錄的讀取權限,則您的文件將不存在。
因此,將find
上面的命令替換為locate
幾乎等效的命令:
$ locate '*.txt' -0 | xargs -0 fgrep texthere
該-0
選項(或--null
在某些系統上)對應--print0
的選項find
。