我有一个目录,里面有许多扩展名的文件。我想递归删除*.srt
以下文件(*.srt
仅限文件):不要结束使用-en.srt
(其中srt
是扩展名)。我想出了以下解决方案,它似乎工作正常,但是,我想知道它是否 100% 正确。
find . -name "*.srt" ! -name "*-en.srt" -type f -exec rm -rf {} \;
答案1
!——首先完整阅读答案,然后如果喜欢的话就使用它——!
您的命令是正确的,但是不需要使用-rf
参数rm
。因为您要删除文件而不是目录。
另一种清晰的写法是(它几乎与您的命令相同):
find -name '*.srt' -and -not -name '*-en.srt' -type f -exec rm '{}' \;
或者按照@steeldriver 建议的你可以使用:
find -name '*.srt' -and -not -name '*-en.srt' -type f -ok rm '{}' \;
它将请求您的许可来删除每个建立的文件。
您也可以使用它-delete
,但rm {} \;
要注意它的危险:
不要忘记 find 命令行被评估为一个表达式,因此将 -delete 放在首位将使 find 尝试删除您指定的起始点以下的所有内容。在测试您稍后打算与 -delete 一起使用的 find 命令行时,您应该明确指定 -depth 以避免以后出现意外。由于 -delete 隐含 -depth,因此您不能同时使用 -prune 和 -delete。
在进行实际工作之前测试一下会发生什么总是一个好主意,因此我建议运行:
find -name '*.srt' -and -not -name '*-en.srt' -type f | grep -i en.srt
如果它什么都不返回,那么实际的命令将毫无问题地工作并且你就可以继续...甚至:
find -name '*.srt' -and -not -name '*-en.srt' -type f | less
检查将要删除的内容。
并且不要忘记引用'{}'
:
(当从 shell 调用 find 时)应该将其引起来(例如,'{}')以防止它被 shell 解释。
答案2
让我们仅使用bash
通配符来实现这一点:启用extglob
和globstar
选项后,
rm **/!(*-en).srt
删除所有以 结尾的文件,不包括当前目录和子目录.srt
中以 结尾的任何文件。 如果您不确定这样的扩展,请通过添加前缀进行测试(参见下面的示例)。-en.srt
echo
例子
$ tree
.
├── 01.srt
├── 02.srt
├── no-en.srt
├── not-en.srt
├── subdir
│ ├── 01.srt
│ ├── 02.srt
│ ├── no-en.srt
│ └── not-en.srt
└── unrelated.png
$ shopt -s extglob globstar
$ echo rm **/!(*-en).srt
rm 01.srt 02.srt subdir/01.srt subdir/02.srt
$ rm **/!(*-en).srt
$ tree
.
├── no-en.srt
├── not-en.srt
├── subdir
│ ├── no-en.srt
│ └── not-en.srt
└── unrelated.png
解释
**/
–globstar
启用该选项后,将匹配任意数量的目录和子目录!(*-en)
–extglob
启用该选项后,它将匹配除给定模式之外的任何内容,因此任何不以-en