117

我在 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

还有另一种方法,以便我可以立即删除选定的文件吗?

4

7 回答 7

173

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

重要的是要注意这个扩展是由 shell 完成的,rm甚至在加载之前。

于 2012-05-09T12:46:57.710 回答
84

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

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

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

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

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

于 2012-05-09T12:46:30.197 回答
45

如果要删除名称与特定形式匹配的所有文件,通配符(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

正则表达式比通配符更强大;您可以将输出提供greprm -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 $(!!)

where!!扩展为上一个命令。或者我可以键入向上箭头或 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 barrm -f 'foo bar'.

于 2013-09-04T15:56:16.743 回答
9

只需在 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
于 2016-07-01T00:26:57.103 回答
5

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

rm -rf abc.log.2012-*

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

于 2012-05-09T19:09:28.917 回答
3

我不是 linux 专家,但我相信您想将输出文件列表通过管道传输到xargs rm -rf. 我过去使用过类似的东西,效果很好。首先在示例目录上进行测试!

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

于 2012-05-09T12:49:05.347 回答
-1

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

rm -rf /log/*
于 2015-08-18T11:44:23.537 回答