我试图用以下命令将数千个文件上载到:
gsutil -m cp *.json gs://mybucket/mydir但我知道这个错误:
-bash: Argument list too long处理这件事最好的方法是什么?显然,我可以编写bash脚本来迭代不同的数字:
gsutil -m cp 92*.json gs://mybucket/mydir
gsutil -m cp 93*.json gs://mybucket/mydir
gsutil -m cp ...*.json gs://mybucket/mydir但问题是,我事先不知道我的文件名是什么,所以编写该命令并不简单。
是否有一种方法可以用gsutil (我不这么认为,从文件中)来处理这个问题,或者在bash中可以一次列出10,000个文件,然后将它们输送到gsutil命令中?
发布于 2017-06-27 13:24:51
Eric的答案应该有效,但另一种选择是通过引用通配符表达式来依赖gsutil的内置通配符:
gsutil -m cp "*.json" gs://mybucket/mydir要解释更多:“参数列表太长”错误来自shell,它为扩展通配符提供了一个有限大小的缓冲区。通过引用通配符,可以防止shell展开通配符,相反,shell将该文字字符串传递给gsutil。然后gsutil以流的方式扩展通配符,即在执行操作时扩展通配符,因此它不需要缓冲无限数量的扩展文本。因此,您可以在任意大的表达式上使用gsutil通配符。在对对象名使用gsutil通配符时,情况也是如此,因此,这样做是可行的:
gsutil -m cp "gs://my-bucket1/*" gs://my-bucket2即使在gs://my 1的顶层有10亿个对象。
发布于 2017-06-27 12:42:01
如果您的文件名在换行符中是安全的,您可以使用gsutil cp的能力从stdin读取,例如
find . -maxdepth 1 -type f -name '*.json' | gsutil -m cp -I gs://mybucket/mydir或者,如果您不确定您的名字是否安全,并且您的find和xargs支持它,那么您可以这样做
find . -maxdepth 1 -type f -name '*.json' -print0 | xargs -0 -I {} gsutil -m cp {} gs://mybucket/mydir发布于 2017-06-27 17:06:18
下面是您可以这样做的一种方法,使用xargs限制同时传递给gsutil的文件数量。空字节用于防止文件名中的空格或换行符出现问题。
printf '%s\0' *.json | xargs -0 sh -c 'copy_all () {
gsutil -m cp "$@" gs://mybucket/mydir
}
copy_all "$@"'在这里,我们定义了一个函数,用于将文件参数放在gsutil命令的正确位置。整个过程应该是处理所有参数所需的最小次数,每次传递文件名参数的最大数量。
或者,您可以分别定义函数,然后export它(这是特定于bash的):
copy_all () {
gsutil -m cp "$@" gs://mybucket/mydir
}
printf '%s\0' *.json | xargs -0 bash -c 'export -f copy_all; copy_all "$@"'https://stackoverflow.com/questions/44780079
复制相似问题