在bash shell中将文件从一个目录移动到另一个目录时,参数列表对于ls而言太长

时间:2018-10-17 15:09:36

标签: bash shell centos redhat

以下是我用于将文件从目录a移至目录b的命令

  ls /<someloc>/a/* | tail -2000 | xargs -I{} mv {} /<someloc>/b/
    -bash: /usr/bin/ls: Argument list too long

文件夹a包含数百万个文件。

需要您的帮助以解决此问题。

2 个答案:

答案 0 :(得分:2)

如果两个目录的位置都在同一磁盘/分区上,并且文件夹b最初为空,则可以执行以下操作

$ rmdir /path/to/b
$ mv /other/path/to/a /path/to/b
$ mkdir /other/path/to/a

如果文件夹b不为空,则可以执行以下操作:

find /path/to/a/ -type f -exec mv -t /path/to/b {} +

如果只想移动2000个文件,则可以

find /path/to/a/ -type f -print | tail -2000 | xargs mv -t /path/to/b

但这对于某些文件名可能是有问题的。一种更干净的方法是使用-print0中的find,但是问题在于headtail无法处理它们,因此您必须使用{{1 }}。

awk

答案 1 :(得分:1)

问题代码中的ls无用。全局(/<someloc>/a/*)会生成文件的排序列表,并且ls仅复制它(重新排序后)(如果它可以正常工作)。有关ls失败的原因,请参见“Argument list too long”: How do I deal with it, without changing my command?

使代码起作用的一种方法是将ls替换为printf

printf '%s\n' /<someloc>/a/* | tail -2000 | xargs -I{} mv {} /<someloc>/b/

printf是Bash内置的,因此运行它不会创建子进程,并且不会发生“参数列表过长”问题。

如果任何文件的名称中包含换行符,此代码仍将失败。对于不易受此问题影响的替代方案,请参见kvantour的答案。