2013-03-01 189 views
5

grep有能力使用-r選項遞歸搜索。然而,我想知道是否grep有能力爲指定數量的子文件夾級別遞歸地搜索查詢字符串。例如,我有一個文件夾root,其中有文件夾parent1, parent2, ..., parentN。每個父文件夾都有正常的文本文件和文件夾,稱爲child1, child2, ..., childM。我想從根級運行grep並搜索父級內的文件,而無需查看子文件夾。有沒有簡單的方法來做到這一點?遞歸使用grep

+1

您想要執行類似以下操作:find/path/to/find -name「nameofthefile」或想要將每個文件檢查一個字符串? – 2013-03-01 22:24:13

回答

6

,你可以嘗試這些了:

的grep

--exclude=GLOB 
       Skip files whose base name matches GLOB (using 
       wildcard matching). A file-name glob can use *, 
       ?, and [...] as wildcards, and \ to quote a wildcard 
       or backslash character literally. 

     --exclude-from=FILE 
       Skip files whose base name matches any of the file-name 
       globs read from FILE (using wildcard matching as 
       described under --exclude). 

     --exclude-dir=DIR 
       Exclude directories matching the pattern DIR from 
       recursive searches. 

或使用該find | xargs grep

與發現,你可以定義級別

編輯

在linux/unix世界中,管道向另一個命令的輸出是非常常見的。我敢打賭,你每天都這樣做。

echo "abc"|sed 's/a/x/' 
find . -name "*.pyc" |xargs rm 
awk 'blahblah' file | sort |head -n2 
tree|grep 'foo' 
mvn compile|ack 'error' 
... 

請注意,並非上述所有示例都是有效的。他們只是例子。

+0

謝謝你的快速回答。你能解釋一下|在你的例子中表示。我知道它可以用來將輸出管道輸出到一個dest,但我不明白如何將輸出管道輸出到不同的命令。無論如何,我正在嘗試您的解決方案,並很快接受您的答案。 – Sal 2013-03-01 22:49:25

+0

@Sal請參閱答案中的編輯,更多管道 – Kent 2013-03-01 23:01:39

10

作爲Kentnotes,你不能用直線grep來做到這一點;它根本不夠強大。訣竅是使用find來確定要搜索的文件,並將find生成的文件列表傳遞給grep

如果您運行的是man find,那麼您將獲得find所需的許多選項的手冊頁。我們感興趣的是-maxdepth

讓我們建立我們需要的命令。在每個階段運行命令來看看是什麼樣子:

  • find .會列出所有存在於當前文件夾(.)或任何後代文件夾中的文件和文件夾。

  • find . -maxdepth 1將列出當前文件夾中的所有文件和文件夾。 find . -maxdepth 2將同樣列出當前文件夾中的所有文件和文件夾以及任何直接子文件夾。等等......

  • 請注意,我們也列出了文件夾;我們不希望這樣,因爲grep無法搜索文件夾本身,只能搜索文件夾中的文件。添加-type f只會獲得列出的文件:find . -maxdepth 2 -type f

現在我們知道我們要搜索的文件,我們需要獲得grep來搜索這些文件。這樣做的標準方法是使用xargs

find . -maxdepth 2 -type f | xargs grep <text-to-search-for> 

|以「標準輸出」,又名「標準輸出」,從find(即你在屏幕上通常看到的)和管道入xarg的「標準輸入「,又名」標準輸入「,即如果您正在輸入正在運行的程序,通常會發生什麼。

xargs是一個狡猾的小程序,在添加了它在標準輸入接收到的所有參數後,會運行您告訴它的任何內容(此處爲grep <text-to-search-for>)。結果是grep將搜索find找到的每個文件。

但是,如果某些文件名中有空格,則這不起作用,因爲xargs認爲空格分隔兩個不同的文件名,而不是一個文件名的一部分。有很多方法可以解決這個問題(理想的做法是不要在文件名中使用空格),最常用的方法是使用find的一個發燒友功能。

如果添加-exec參數find,將執行一切你指定長達;+。如果添加{}(即文字字符{}),它將用所有文件的列表替換。由於find正在這樣做,它知道文件名中的空格應該在文件名中。

所以做你想要什麼最好的辦法是這樣的:

find . -type f -maxdepth 2 -exec grep <text-to-search-for> {} + 

(與+;結束之間的差異使得這裏沒有什麼區別。如果你有興趣它在man find,但。簡短版本是+更快,但意味着您只能在命令中使用一個{}。)