如何在 Linux 上的 Bash 中一次删除多个文件?

问题描述 投票:0回答:8

我在 Linux 服务器上有以下文件列表:

abc.log.2012-03-14
abc.log.2012-03-27
abc.log.2012-03-28
abc.log.2012-03-29
abc.log.2012-03-30
abc.log.2012-04-02
abc.log.2012-04-04
abc.log.2012-04-05
abc.log.2012-04-09
abc.log.2012-04-10

我一直在使用命令

rm -rf
一一删除选定的日志文件,如下所示:

rm -rf abc.log.2012-03-14
rm -rf abc.log.2012-03-27
rm -rf abc.log.2012-03-28

有没有其他方法可以一次性删除选中的文件?

linux bash rm
8个回答
198
投票

Bash 支持各种通配符和扩展。

您的确切情况将通过大括号扩展来处理,如下所示:

$ rm -rf abc.log.2012-03-{14,27,28}

上面的内容将扩展为带有所有三个参数的单个命令,并且相当于键入:

$ rm -rf abc.log.2012-03-14 abc.log.2012-03-27 abc.log.2012-03-28

需要注意的是,这种扩展是在

rm
加载之前由 shell 完成的。


95
投票

使用通配符 (

*
) 来匹配多个文件。

例如,以下命令将删除所有名称以

abc.log.2012-03-
开头的文件。

rm -f abc.log.2012-03-*

我建议运行

ls abc.log.2012-03-*
列出文件,以便您可以在运行
rm
命令之前看到要删除的内容。

有关更多详细信息,请参阅有关 文件名扩展的 Bash 手册页。


51
投票

如果要删除名称与特定形式匹配的所有文件,通配符(glob 模式)是最直接的解决方案。一些例子:

$ rm -f abc.log.*             # Remove them all
$ rm -f abc.log.2012*         # Remove all logs from 2012
$ rm -f abc.log.2012-0[123]*  # Remove all files from the first quarter of 2012

正则表达式比通配符更强大;您可以将

grep
的输出提供给
rm -f
。例如,如果某些文件名以
"abc.log"
开头,另一些以
"ABC.log"
开头,则
grep
允许您执行不区分大小写的匹配:

$ rm -f $(ls | grep -i '^abc\.log\.')

如果任何文件名包含有趣的字符(包括空格),这将导致问题。小心点。

当我这样做时,我首先运行

ls | grep ...
命令并检查它是否产生我想要的输出 - 尤其是如果我使用
rm -f
:

$ ls | grep -i '^abc\.log\.'
(check that the list is correct)
$ rm -f $(!!)

其中

!!
扩展为上一个命令。或者,我可以输入向上箭头或 Ctrl-P 并编辑上一行以添加
rm -f
命令。

这假设您使用的是 bash shell。其他一些 shell,特别是 csh 和 tcsh 以及一些较旧的 sh 派生 shell,可能不支持

$(...)
语法。您可以使用等效的反引号语法:

$ rm -f `ls | grep -i '^abc\.log\.'`

$(...)
语法更容易阅读,如果你真的有野心,它可以嵌套。

最后,如果您要删除的文件子集无法轻松地用正则表达式表达,我经常使用的一个技巧是将文件列出到临时文本文件中,然后对其进行编辑:

$ ls > list
$ vi list   # Use your favorite text editor

然后我可以手动编辑

list
文件,只保留我要删除的文件,然后:

$ rm -f $(<list)

$ rm -f `cat list`

(同样,这假设所有文件名都不包含有趣的字符,特别是空格。)

或者,在编辑

list
文件时,我可以将
rm -f 
添加到每行的开头,然后:

$ . ./list

$ source ./list

编辑文件还可以在必要时添加引号,例如将

rm -f foo bar
更改为
rm -f 'foo bar'
.


16
投票

只需在 sublime 中使用多行选择将所有文件组合成一行,并在每个文件名之间添加一个空格,然后在列表的开头添加

rm
。当您要删除的文件名中没有模式时,这非常有用。

[$]> rm abc.log.2012-03-14 abc.log.2012-03-27 abc.log.2012-03-28 abc.log.2012-03-29 abc.log.2012-03-30 abc.log.2012-04-02 abc.log.2012-04-04 abc.log.2012-04-05 abc.log.2012-04-09 abc.log.2012-04-10

6
投票

通配符可以很好地解决此问题,但为了安全起见,最好尽可能少地使用通配符,因此大致如下:

rm -rf abc.log.2012-*

虽然从表面上看,这些只是单个文件吗?如果这些项目都不是目录,则不需要递归选项,因此最好不要使用它,只是为了安全起见。


4
投票

我不是 Linux 专家,但我相信您想将输出文件列表通过管道传输到

xargs rm -rf
。我过去使用过类似的东西,效果很好。首先在示例目录上进行测试!

编辑 - 根据出现的其他答案,我可能误解了。如果您可以使用通配符,那就太好了。我假设您显示的原始列表是由程序生成的,以便为您提供“选择”,所以我认为通过管道传输到

xargs
将是正确的选择。


0
投票

如果您想一次删除属于某个目录的所有文件。 例如: 您的目录名称是“log”,“log”目录包括abc.log.2012-03-14,abc.log.2012-03-15,...等文件。您必须位于日志目录之上并且:

rm -rf /log/*

0
投票

我想一步删除多个未被通配符覆盖的文件是什么?

© www.soinside.com 2019 - 2024. All rights reserved.