2012-07-01 88 views
10

我想找到不包含特定字符串的文件(位於目錄及其子目錄中)並刪除這些文件。我如何做到這一點?刪除不包含特定字符串的文件

+0

刪除意味着排除。對? –

+2

@SivaCharan是啊...從存在:) –

+0

刪除我的意思是:刪除 – Hakim

回答

0

一種可能性是

find . -type f '!' -exec grep -q "my string" {} \; -exec echo rm {} \; 

可以刪除echo如果預覽看起來是正確的。

+1

你的意思是'grep -v'? – rodion

+0

This Works,+1。 –

+0

這對我不起作用。我可以看到rm命令正在命令行中運行,但在完成命令後沒有任何內容被刪除。所有文件都存在。我手動檢查了這些文件,並看到其中一些文件中沒有包含字符串... – Hakim

-1

編輯:這就是你如何不應該做到這一點!原因是here。感謝@ormaaj指出它!

find . -type f | grep -v "exclude string" | xargs rm 

注:grep模式將對陣從當前目錄完整的文件路徑(見find . -type f輸出)

+1

Downvote不是我,但僅供參考,可能是由於[xargs](http://mywiki.wooledge.org/UsingFind#Actions_in_bulk:_xargs .2C_-print0_and_-exec_.2B-) – ormaaj

+0

@ormaaj OMG!我曾經經常使用它(xx;)感謝您指出它。 – rodion

5

GNU的grep和bash。如果需要便攜性,請使用find解決方案。這稍微快一點。

+0

@ Peter.O奇怪,我無法重現。它看起來如果使用'-r',它除了默認文件外別無選擇,除非明確給出'-'。不過,'.'可能是一個好主意。添加它。 – ormaaj

+0

當您添加'.'時,我已經刪除了我的原始評論,因爲您一定會看到,但我也有點困惑,因爲'man grep'顯示了最後一個[FILE ...]選項......但這絕對是這裏發生的事情(即等待輸入,沒有'。'); * GNU grep 2.5.4 * –

+1

默認的「。」對於grep -r被添加到grep 2.11中,相當新近。而且GNU不尊重man頁面。 –

1

我可以想出幾種方法來解決這個問題。這裏有一個:find和grep來生成一個沒有匹配的文件列表,然後xargs rm他們。

find yourdir -type f -exec grep -F -L 'yourstring' '{}' + | xargs -d '\n' rm 

這是假設的GNU工具(grep的-L和xargs的-d都是非便攜式),當然沒有文件名與他們換行。它具有每個文件不運行一次grep和rm的優點,所以它會相當快。我建議用「echo」代替「rm」來測試它,只是爲了確保它在釋放破壞之前選擇正確的文件。

+3

這個人不是在做[xargs](http://mywiki.wooledge.org/UsingFind#Actions_in_bulk:_xargs.2C_-print0_and_-exec_.2B-)。如果使用xargs,'-0'是唯一的方法。 – ormaaj

+0

-d'\ n'是一種很好的方式,直到你得到一個帶有換行符的文件名爲止。它禁用了大部分的xargs愚蠢,就像-0一樣。不過很高興瞭解grep -Z。 –

+1

一個帶有換行符的文件名?那個在鍵盤上有貓的傢伙呢?他不能像這樣輸入長命令!你好,這太瘋狂了。但你可以在YouTube上找到。 –

6

下面的工作:

find . -type f -print0 | xargs --null grep -Z -L 'my string' | xargs --null rm 

這將首先使用發現打印的所有文件的名稱在當前目錄和所有子目錄。這些名稱都印有一個空終止而不是通常的換行分離器(嘗試的輸出輸送至od -c看到-print0參數的效果。

然後--null參數xargs告訴它接受空終止輸入。xargs然後將調用grep文件名列表上。

-Z參數grep作品像-print0參數find,所以grep的將打印出它的結果空值終止的(這就是爲什麼xargs最後調用需要--null選項太)-L參數grep導致grep打印命令行上這些文件的文件名(即xargs增加了),這匹配的正則表達式:

我的字符串

如果您想要沒有正則表達式魔法的簡單匹配,請添加-F選項。如果你想要更強大的正則表達式,那麼給一個-E參數。使用單引號而不是雙引號是一種很好的習慣,因爲這可以保護您免受應用於字符串的任何shell魔法(例如變量替換)

最後,您再次撥打xargs可以刪除所有文件,與前面的電話發現。

直接從find命令調用grep-exec爭論的問題是,grep然後得到一整批處理文件作爲xargs確實調用一次每個文件,而不是一次。如果你有很多文件,這是很多更快。也不要試圖做的東西,如:

rm $(some command that produces lots of filenames) 

它總是更好,因爲這個知道最大命令行限制,並會調用每次rm多次與儘可能多的參數,因爲它可以將它傳遞給xargs

請注意,如果不需要處理包含空白區和新行的文件,該解決方案會更簡單。

或者

grep -r -L -Z 'my string' . | xargs --null rm 

將工作太(和較短)。 -r參數grep會導致它讀取目錄中的所有文件,並遞歸地下降到任何子目錄中)。如果您還想對文件進行一些其他測試(如年齡或權限),請使用find ...方法。

請注意,任何帶單個破折號導入符的單個字母參數都可以組合在一起(例如-rLZ)。但是請注意,find不使用相同的約定,並且具有用單個短劃線引入的多字母參數。這是出於歷史原因,並且從來沒有被修復,因爲它會打破太多的腳本。

+0

好的解釋! –

相關問題