在我的一个程序中,我调用一个bash
命令来删除目录中的所有文件,但其中一些文件:
bash -c
shopt -s extglob
shopt -s nullglob
rm /path/to/directory/!("file1" | "file2")
据我了解,这意味着“在此命令上使用 bash,使用扩展模式,删除除这些之外的所有文件”
它工作得很好,但是会删除除命令中的文件之外的所有文件。
我想要的是删除目录中的所有 .mp4 和 .zip,但我在命令中放入的内容。
我想我必须在命令中的某个位置添加 *.mp4 和 *.zip,但我不知道在哪里。
编辑:为了清楚起见,我需要的是“删除所有 .mp4 和 .zip 文件,但保留这些文件”
答案1
该模式!("file1" | "file2")
匹配除空格file1␣
之外的任何文件。您引用它的方式具有误导性:它相当于or )`。␣file2
␣
!(file1 | file2)
!("file1 "|" file2
bash 中没有办法将否定模式与肯定模式结合起来表示“除了那些之外的所有这些”。在zsh中,你可以这样写
setopt extended_glob
rm /path/to/directory/*.(mp4|zip)~(keep*|1234.zip)
删除this.mp4
andthat.zip
但不删除keep-this.mp4
or 1234.zip
。
在 bash 中,您可以设置GLOBIGNORE
多变的从所有匹配中排除某些模式。
shopt -s extglob
GLOBIGNORE='keep*:1234.zip'
rm /path/to/directory/*.(mp4|zip)
unset GLOBIGNORE
或者,您可以使用find
,它可以让您构建任意复杂的布尔表达式。
find /path/to/directory \( -name '*.mp4' -o -name '*.zip' \) ! -name 'keep*' ! -name '1234.zip' -delete
请注意,find
递归到子目录。如果不需要,请-maxdepth 1
在 后添加/path/to/directory
。
如果您find
不明白-maxdepth
(这是常见但不标准),请改用-type d -prune -o
。如果您find
不明白-delete
(相同的评论),请-exec rm {} +
改为使用。
答案2
有以下几种方法:
- 使用 find (可移植,因为它不需要特定的 shell [bash])
寻找 。 -最大深度1! -名称“排除”-删除
或者如果您有多种模式:
寻找 。 -最大深度1! \(-name“排除”-o -name“排除2”\)-exec rm -f {}\+
- 使用 GLOBIGNORE 变量(仅限 bash)
导出 GLOBIGNORE=排除:排除1:掩码*
这将从全局中排除提到的文件和掩码。之后您可以指定rm your_pattern
你可以先尝试一下ls
答案3
我愿意你找到。然而你的问题是空间。
rm /path/to/directory/!("file1" | "file2")
是相同的
rm "/path/to/directory/!(file1" "|" "file2)"
不是
rm "/path/to/directory/!(file1|file2)"
阅读 shell 引用规则。