2014-07-01 28 views
5

如何遞歸刪除以.foo結尾的所有文件,其中包含同名文件,但結尾爲.bar?例如,考慮下面的目錄樹:使用相應的「* .bar」文件遞歸刪除所有「* .foo」文件

. 
├── dir 
│   ├── dir 
│   │   ├── file4.bar 
│   │   ├── file4.foo 
│   │   └── file5.foo 
│   ├── file2.foo 
│   ├── file3.bar 
│   └── file3.foo 
├── file1.bar 
└── file1.foo 

在這個例子中file.foofile3.foofile4.foo將被刪除,因爲有兄弟file{1,3,4}.bar文件。 file{2,5}.foo應該被單獨留在家中留下這樣的結果:

. 
├── dir 
│   ├── dir 
│   │   ├── file4.bar 
│   │   └── file5.foo 
│   ├── file2.foo 
│   ├── file3.bar 
└── file1.bar 
+3

對於一個很好地說明的問題+1。 – shellter

+0

並感謝現有的「樹」。 :P http://linux.die.net/man/1/tree – KPthunder

回答

6

記得先備份你試試這個findrm命令。

使用此find

find . -name "*.foo" -execdir bash -c '[[ -f "${1%.*}.bar" ]] && rm "$1"' - '{}' \; 
+1

很好地完成!對於OP來說,只需要注意一下,爲了匹配'xargs'的性能,可以使用'+'符號來並行處理文件。 –

+0

+1我不明白'$ {1%。*}'我在玩,'$ {1%}'會返回分機。我在哪裏可以找到更多關於這個? – Tiago

+0

@Tiago:感謝您可以在'man bash'中找到查看'Parameter Expansion'部分。 – anubhava

2
while IFS= read -r FILE; do 
    rm -f "${FILE%.bar}".foo 
done < <(exec find -type f -name '*.bar') 

或者

find -type f -name '*.bar' | sed -e 's|.bar$|.foo|' | xargs rm -f 
1

bash 4.0及更高版本,以及在zsh

shopt -s globstar # Only needed by bash 
for f in **/*.foo; do 
    [[ -f ${f%.foo}.bar ]] && rm ./"$f" 
done 

zsh,只有存在對應的.bar文件時,才能定義匹配以.foo結尾的文件的選擇性模式,因此rm僅被調用一次,而不是每個文件調用一次。

rm ./**/*.foo(e:'[[ -f ${REPLY%.foo}.bar ]]':) 
+1

爲防萬一,我總是在這樣的globbed文件名之前使用「 - 」,並且用戶可能想要設置GLOB_DOTS(具有類似於「find」的結果):'rm - **/*。foo(De :'[[-f $ {REPLY%.foo} .bar]]':)' – vinc17

+0

好點。我已經編輯了使用'。/'而不是'--'的答案,因爲這將適用於任何'rm'的實現。 – chepner

相關問題