在 Bash 中,如何在提供多个异常的同时针对通配符 rm 文件?

在 Bash 中,如何在提供多个异常的同时针对通配符 rm 文件?

我有以下文件列表:

main.acn
主程序.acr
主程序.alg
主辅助文件
主程序.glg
主程序.glo
主程序.gls
主要的
主程序.lof
主日志
主批次
主程序.nlo
主输出
主要.pdf
主文件
主目录

我想 rm 所有main.*文件,除了主文件主要.pdf文件。

我尝试过,rm main.* !("main.tex","main.pdf")但这没有用,并且main.* 无一例外地删除了所有内容。

有任何想法吗?

答案1

!("main.tex","main.pdf")匹配任何不是 的内容main.tex,main.pdf,因此可能匹配目录中的所有文件。

需要注意的关键是!(...)已经表现得像*,因为它本身与不属于其中之一的任何内容相匹配。分隔符是|, 不是,

所以,main.!(tex|pdf)应该有效。或者,!(main.tex|main.pdf)如果您想删除除这两个文件之外的所有文件,而不仅仅是名称以main..

看:

答案2

不太复杂的方法是保存要保留的文件,删除所有内容(其他),然后再次放回保存的文件。它也是一个符合 POSIX 标准的解决方案:

mkdir x                   # File or directory must not already exist
mv main.tex main.pdf x    # Save the files you want to keep
rm ./*                    # Ignore the error about not deleting 'x'
mv x/* .                  # Restore everything you saved. Notice the dot!
rmdir x                   # Tidy up

这里我选择了x一个尚不存在的文件或目录。你将要rm收到无法删除的错误x;那挺好的。不使用rm -rf

请注意,通常rm ./*会跳过点文件。

答案3

在 Bash 中还有一个GLOBIGNORE变量,它可以从 glob 返回的列表中排除/删除名称。一个例子:

$ touch main.pdf main.tex one.pdf one.tex three.wow two.pdf two.tex
$ echo *
main.pdf main.tex one.pdf one.tex three.wow two.pdf two.tex
$ GLOBIGNORE='main.tex:main.pdf'
$ echo *
one.pdf one.tex three.wow two.pdf two.tex

GLOBIGNORE可以是描述要忽略的名称的表达式列表(以冒号分隔),如上面的示例所示。您的问题是关于排除一对简单的文件名,但您也可以使用 glob 表达式:

$ GLOBIGNORE='one.*:two.*'
$ echo *
main.pdf main.tex three.wow

与glob 匹配的名称列表(*在这些示例中)根据 中的表达式进行计算GLOBIGNORE。与任何表达式匹配的名称将从列表中删除。这是一个有用的功能。

在许多情况下,使用 也很有用export,例如export GLOBIGNORE='main.tex:main.pdf'

答案4

每当我遇到这样的情况时,我都会用管道来解决:

ls -1 主。* | egrep -v '\.pdf|\.tex' | xargs rm

相关内容