【问题标题】:Recursively deleting all "*.foo" files with corresponding "*.bar" files递归删除所有带有相应“*.bar”文件的“*.foo”文件
【发布时间】:2014-08-22 09:21:32
【问题描述】:

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

.
├── 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

【问题讨论】:

标签: bash unix recursion zsh


【解决方案1】:

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

使用这个find

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

【讨论】:

  • 干得好! OP 只需一个注释,以匹配xargs 的性能,可以使用+ 表示法并行处理文件。
  • +1 我不明白 ${1%.*} 我在玩,${1%} 会返回扩展名。我在哪里可以找到更多相关信息?
  • @Tiago:谢谢你可以在man bash 找到Parameter Expansion 部分。
【解决方案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

【讨论】:

    【解决方案3】:

    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 ]]':)
    

    【讨论】:

    • 以防万一,我总是在这样的全局文件名之前使用“--”,用户可能想要设置 GLOB_DOTS(以获得类似于“find”的结果):rm -- **/*.foo(De:'[[ -f ${REPLY%.foo}.bar ]]':)跨度>
    • 好点。我已将答案编辑为使用./ 而不是--,因为它适用于rm 的任何实现。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-07-16
    • 2017-10-05
    • 1970-01-01
    • 2011-12-22
    • 1970-01-01
    • 1970-01-01
    • 2015-04-22
    相关资源
    最近更新 更多