我想从命令行将大型数据库缩减为 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
并且不能-z
与sort
and/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