2012-07-19 61 views
10

我成功使用find來創建當前子目錄中的所有文件的列表,不包括子目錄「緩存」中的所有文件。這是我的第一位代碼:管道找到grep進行快速目錄排除的結果

find . -wholename './cach*' -prune -o -print 

我現在希望將其管理爲grep命令。它似乎應該很簡單:

find . -wholename './cach*' -prune -o -print | xargs grep -r -R -i "samson" 

...但這是返回的結果,主要是從緩存目錄。我試過刪除xargs引用,但是這樣做的確如你所期望的那樣,在文件名的文本上運行grep,而不是在文件本身上運行。我的目標是在任何沒有緩存內容的文件中找到「samson」。

我可能會在這個例子中使用加倍的greps來解決這個問題,但我很好奇爲什麼這個單行程的行爲是這樣的。我很想聽到有關如何修改它的想法,同時仍然使用這兩個命令(因爲這樣做有速度優勢)。

(這是在CentOS 5的,順便說一句。)

回答

9

wholename比賽,可爲什麼它仍然包括「緩存」文件的原因。如果您在包含「緩存」文件夾的目錄中執行find命令,它應該可以工作。如果不是,請嘗試將其更改爲-name '*cache*'

此外,您不需要-r-R爲您的grep,它告訴它通過目錄遞歸 - 但您正在測試單個文件。

您可以使用管道版本,或單命令來更新你的命令:

find . -name '*cache*' -prune -o -print0 | xargs -0 grep -il "samson" 

find . -name '*cache*' -prune -o -exec grep -iq "samson" {} \; -print 

注意,在第一個命令的-l告訴grep爲「列出文件「而不是匹配的行。第二個中的-q確實相同;它會告知grep安靜地響應,因此find將只打印文件名。

+0

謝謝!遞歸的去除對我來說是個訣竅。 (舊習慣很難死掉,順便說一句,這是我的一個錯誤類型,因爲我通常使用「-r -i -I」,這比冗餘遞歸標誌更有意義)。「全名」部分很好,因爲不需要的子目錄確實在當前目錄的根目錄中。所以現在是: 'find。 -wholename'./cach*'-prune -o -print | xargs grep -i -I「samson」' – eternalnewb 2012-07-19 17:01:51

+0

太棒了,很高興這很簡單=] – newfurniturey 2012-07-19 17:04:26

3

使用-exec選項上發現的而不是將它們管道到另一個命令。從那裏您可以使用grep "samson" {} \;在列出的每個文件中查找samson。

例如:

find . -wholename './cach*' -prune -o -exec grep "samson" "{}" + 
3

你已經告訴grep本身進行遞歸(兩次!-r-R是同義詞)。由於您傳遞的參數之一是.(頂層目錄),因此grep正在每個文件中進行搜索(其中一些文件是兩次,如果它們在子目錄中則更多)。

如果你打算使用findgrep,這樣做:

find . -path './cach*' -prune -o -print0 | xargs -0 grep -i "samson" 

使用-print0-0,使你的腳本工作,甚至包含空格或標點字符的文件名。

然而,你可能不需要在這裏與find打擾,因爲GNU的grep能夠排除目錄:

grep -R --exclude-dir='cach*' -i "samson" . 

(這也排除了./deeply/nested/directory/cache如果您只想排除在緩存目錄。頂層,請使用find

+0

如果當前文件夾/路徑中的文件太多,單個'grep'將返回一個「太多參數」的錯誤 - 所以你需要注意這一點。 – newfurniturey 2012-07-19 17:03:16

+0

感謝您的支持!正如在「接受」答案中提到的那樣,立即清理那些固定的東西。你們很棒。 – eternalnewb 2012-07-19 17:04:54

+0

@newfurniturey不,如果命令行太長(例如,如果我寫了'grep ... *'並且有很多文件),那麼shell會出現「太多參數」錯誤。這裏沒有shell匹配,命令行恰好是43個字符。 – Gilles 2012-07-19 17:12:58