如何删除文件夹中除最新的三个文件外的所有文件

10

我有一个文件夹,其中包含一些子版本控制检出(当运行capistrano部署脚本时进行检出)。

实际上我想要做的是保留最新的3个版本,而删除其他版本,为此我计划在终端上使用某些命令来运行一个运行命令,实际上capistrano在这里并没有什么作用,只是一个unix命令。

我尝试运行一个命令来获取除了最后三个以外的文件列表并删除其余的文件,我可以使用以下命令获取文件列表:

(ls -t /var/path/to/folder |head -n 3; ls /var/path/to/folder)|sort|uniq -u|xargs

现在,如果我在这个命令的末尾添加一个rm -Rf,它会返回文件未找到以删除。很明显,这是因为它只返回文件夹的名称,而不是文件夹的完整路径。
有没有一种方法可以使用一个Unix命令删除这些文件/文件夹?
3个回答

17

好的,您的脚本有几个问题。

首先,最严重的问题是这一行:

ls -t /var/path/to/folder |head -n 3;
ls -t | head -n 3 命令会返回按文件最后修改时间排序的文件列表,以最近修改的文件为开头。 head -n 3 表示只列出前三行。因此它的作用是“给我一个仅包含最近修改的三个文件的列表”,这不是你想要的。

我不确定你在第二个 ls 命令中要做什么,但我很确定那只会将目录中所有文件连接到你的列表中。这意味着当它被 sortuniq 处理时,你将只得到该目录中所有文件的字母顺序列表。当传递到像 xargs rm 这样的命令时,你将删除该目录中所有内容

接下来,sort | uniq 不需要 uniq 部分。你可以直接在 sort 上使用 -u 开关来去除重复项。你根本不需要这一部分。

最后,进行目录删除的操作。对于这一点,在你的问题中已经说得很清楚了:只需使用 rm -r

以下是我能想到的最简单的方法:

ls -t1 /var/path/to/folder | tail -n +4 | xargs rm -r

这里发生的情况如下:
  • ls -t1 打印出/var/path/to/folder中所有文件/目录的列表,每行一个,按最近修改日期排序。
  • tail -n +4 打印ls -t1输出的第四行及以后的所有行(即不会列出最近修改的三个文件)。
  • xargs rm -r 告诉计算机删除从tail输出的任何文件。-r表示递归删除文件,所以如果遇到一个目录,它将删除该目录中的所有内容,然后删除目录本身。

请注意,我没有对任何内容进行排序或删除重复项。因为:

  • ls仅报告一次文件,因此没有重复项需要删除
  • 无论以什么顺序删除文件,您都会删除传递的每个文件,所以顺序并不重要。

这些解释是否清楚易懂?

编辑:

由于我错误地认为在传递绝对目录时ls会指定完整路径,而且您可能无法执行cd命令,因此您可以使用tail命令。

例如:

 ls -t1 /var/path/to/folder | tail -n +4 | xargs find /var/path/to/folder -name $1 | xargs rm -r

你好,感谢回复。但是我仍然只能获取文件名,我的主要需求之一是从服务器的任何目录运行此代码并删除该var/path/to/folder中的文件。如果我在相同的文件夹var/path/to/folder中,这个功能可以正常工作。 - nivanka
@nivanka:真的很奇怪。你是指定相对路径还是绝对路径?如果您想从服务器上的任何目录运行此文件,则需要指定绝对路径。您能复制/粘贴您正在使用的确切命令吗? - AgentConundrum
嗨,这是我所做的事情 ls -t1 /var/path/to/folder | tail -n +4 | xargs rm -r - nivanka
@nivanka:显然,我刚才错了,传递绝对路径并没有导致完整路径输出。对此感到抱歉。我想你唯一能做的就是将当前路径存储在一个变量中,cd/var/path/to/folder,运行我给你的代码,然后使用该变量 cd 回原始路径。这是我能做的最好的事情了,抱歉。 - AgentConundrum
我认为在这种情况下不需要-1,因为ls函数的行为取决于输出是否为tty - 参见http://unix.stackexchange.com/a/22164/28597 - JZeolla
显示剩余3条评论

4
以下是完成任务的有用方法.......!!
对于Linux和HP-UX: ls -t1 | tail -n +50 | xargs rm -r # 保留最新的50个文件/目录.
对于SunOS:
rm `(ls -t |head -n 100; ls)|sort|uniq -u`

Mac OSX怎么样,我想它应该是Unix的一个变种? - Khom Nazid

0

嗨,我找到了一种方法可以做到这一点,我们可以使用Unix的&&符号。

因此,命令将看起来像这样:

cd /var/path/to/folder && ls -t1 /var/path/to/folder | tail -n +4 | xargs rm -r

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接