放慢“分裂”速度

放慢“分裂”速度

我有一个非常大的档案,由非常小的文件组成,连接成一个文本文件,并带有“”分隔符。对于较小的档案,我将split 使用“”作为模式进行档案,然后处理生成的文件。然而,在这个存档中,此类文件的数量级约为一亿个——显然,对于将它们全部放入一个目录来说太多了。我创建了文件夹aaab等,以便尝试将它们移动到创建的目录中。但是,我遇到了问题。我尝试过的事情:

  1. 没有命令可以split对结果文件执行任何命令。所以我必须用手做。

  2. **使用将文件移动到目录中find . -name "xaa*" -exec mv {} aa \+不起作用,因为{}不在行尾。

  3. 用于反转源和目标的标志-t在我的 Unix 版本中不可用。

  4. find我必须将into的输出通过管道传输xargs,才能正常工作。

然而,这太慢了——文件的创建速度比它们的移动速度快得多。

  1. 我怀疑xargs一次处理的文件比使用\+after 少find -exec。我尝试添加一个“-R 6000”标志,以便一次运行 6000 个条目;但是,我认为这没有什么区别。

  2. 我将 的优先级降低split到尽可能低。它消耗的 CPU 量没有变化,所以可能也没有影响。

  3. 我打开最多七个命令提示符来运行mv命令(每个命令提示符最后四个字母)——但是,这仍然不够。我会打开更多,但是一旦系统达到七个,响应就太慢了,我不得不停止分裂。例如,在等待ls -l | tail命令返回某些内容时,源存档会被复制到 USB。

所以我一直在做的是,split在此时停止,等待mv 命令赶上,然后重新启动分割。那时我会用来 find -exec rm {} \+删除我已经拥有的文件;这有点快,所以当它到达我没有的文件时,周围的文件就会减少。

因此,第一次此类迭代持续了约 300 万个文件,下一个约 200 万个文件,下一个约 1.5 个文件。不过,我确信应该有更好的方法。还有什么想法可以尝试吗?

答案1

类似的东西xargs -I {} ... mv {} aa仍然会mv在每行输入中运行一次。从POSIX 规范-I的选项xargs

Insert mode: utility is executed for each  logical  line  from  standard  input.

您需要类似的东西xargs -r sh -c 'mv "$@" aa' _(或者在那时,只是)来真正为多个文件find ... -exec sh -c 'mv "$@" aa' _ {} +运行单个文件。mv这样,您就可以使用 shell 在mv目标目录之间插入参数。

  • "$@"被 shell 替换为所有参数,没有任何字段分割或通配符。
  • 的作用与指定的脚本_相同。之后的参数将是、等,或者统称为。$0sh -c$1$2$@

即使这样,我认为你find也会参与竞争条件。它可能会在split结束之前完成目录列表的读取,因此可能无法处理所有文件。它还可能最终递归到您创建的子目录并检测之前移动到那里的文件,并且可能最终尝试再次移动aa/xaaaa/出错(但是,-exec ... {} +忽略命令的退出状态)。

相关内容