递归地从目录中删除除 N 个文件之外的所有文件

递归地从目录中删除除 N 个文件之外的所有文件

我想从命令行将大型数据库缩减为 N 个文件,非常类似于问题确实如此。唯一的区别是我的大多数文件都在子目录中,所以我想知道是否有快速修复我的问题的方法,或者是否需要更深入的操作。目前,我的命令如下所示(用(N+1)适当的数字替换):

find . -type f | sort -R | tail -n +(N+1) | xargs rm

我最初认为这会起作用,因为 find 本质上是递归的,然后我尝试-r在周围添加(递归标志),rm因为输出表明它正在随机选择文件,但找不到要删除的文件。有什么想法吗?

编辑:我的新命令如下:

find . -type f -print0 | sort -R | tail -n +(N+1) | xargs -0 rm

现在我收到错误消息rm: missing operand。此外,我在 CentOS 机器上,因此该-z标志对我来说不可用。

编辑#2此命令运行:

find . -type f -print0 | sort -R | tail -n +(N+1) | xargs -0 -r rm

但是当我执行 afind . -type f | wc -l来获取目录中的文件数量(如果命令正常工作,应该是 N )时,文件的数量与起始数量相比并没有改变。

答案1

如果您需要使用find … -print0并且不能-zsortand/or使用tail,则有一个可行但麻烦的解决方法((N+1)照常替代):

find . -type f -printf "%i\n" | sort | uniq | sort -R | tail -n +(N+1) |
   while read i; do
      find . -type f -inum "$i" -delete
   done

这个肮脏的伎俩是我们使用 inode 编号而不是路径。

内部find会删除当前目录下具有给定 inode 编号的所有文件,因此如果某些文件彼此硬链接,那么您要么全部丢失它们,要么全部保留它们。

预备步骤sort | uniq是为了避免由于硬链接导致重复的 inode 编号而造成过多损失。最终可能会出现超过 100 个文件名,总共N指向多达 100 个不同的 inode。N

如果你find不明白-delete,请使用-exec rm {} +

答案2

我在 osx 上做过类似的事情

find . -type f -print | sort | uniq | sort --random-sort | tail -n +1000 | xargs rm -f

我的 N 是1000。然后你可以用 再次检查剩余文件数是否正确ls | wc -l。另请参阅https://stackoverflow.com/a/20307392/630752

相关内容