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

我有一个 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

是否有其他方法,以便我可以立即删除选定的文件?

314699 次浏览

使用通配符(*)匹配多个文件。

例如,下面的命令将删除所有名称以 abc.log.2012-03-开头的文件。

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

我建议运行 ls abc.log.2012-03-*来列出这些文件,这样您就可以在运行 rm命令之前看到要删除的内容。

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

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

Your exact case would be handled by 支撑扩张, like so:

$ 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 完成的。

我不是一个 linux 专家,但是我相信您希望将您的输出文件列表通过管道传送到 xargs rm -rf。我以前用过类似的东西,效果不错。首先测试一个示例目录!

编辑-我可能有误解,基于其他答案出现。如果可以使用通配符,那就太好了。我假设您显示的原始列表是由一个程序生成的,以提供您的“选择”,所以我认为通过管道到 xargs将是一种方法。

通配符可以很好地解决这个问题,尽管为了安全起见,最好尽可能少地使用通配符,因此,可以这样做:

rm -rf abc.log.2012-*

不过看起来,这些只是单独的文件吗?如果这些项中没有一个是目录,那么递归选项就不是必需的,所以为了安全起见,最好不要使用递归选项。

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

$ 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'

如果要立即删除属于某个目录的所有文件,则。 例如: 您的目录名是“ log”,“ log”目录包括 abc.log.2012-03-14,abc.log.2012-03-15,... etc 文件。你必须在日志目录之上,并且:

rm -rf /log/*

只需使用升华中的多行选择将所有文件组合成一行,并在每个文件名之间添加一个空格,然后在列表的开头添加 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