递归删除所有带有“* .bar”文件的“* .foo”文件

时间:2014-07-01 18:03:44

标签: bash unix recursion zsh

如何以递归方式删除以.foo结尾的所有文件,这些文件的兄弟文件同名,但以.bar结尾?例如,请考虑以下目录树:

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

在此示例file.foo中,file3.foofile4.foo将被删除,因为有兄弟file{1,3,4}.bar个文件。应该留下file{2,5}.foo留下这个结果:

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

3 个答案:

答案 0 :(得分:6)

请记住在尝试此findrm命令之前先进行备份。

使用此find

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

答案 1 :(得分: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

答案 2 :(得分: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中,只有存在相应的.foo文件时,才能定义匹配以.bar结尾的文件的选择模式,以便rm仅调用一次而不是每个文件一次。

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