在 Google Cloud Storage 上批量重命名对象

Posted

技术标签:

【中文标题】在 Google Cloud Storage 上批量重命名对象【英文标题】:Mass rename objects on Google Cloud Storage 【发布时间】:2015-01-25 19:14:17 【问题描述】:

是否可以使用 gsutil(或其他工具)批量重命名 Google Cloud Storage 上的对象?我正在想办法将一堆图像从 *.JPG 重命名为 *.jpg。

【问题讨论】:

【参考方案1】:

是的,有可能:

Move/rename objects and/or subdirectories

【讨论】:

看到但不太确定它如何帮助我批量重命名对象? @Andrei 但我不能在我的 gae 项目中使用 gsutil + subprocess GAE 项目中不需要 gsutil。您可以简单地检索代码中的对象列表并重命名它们。 @AndreiVolgin 目前我正在使用gcs client library 来复制、列出、统计、删除存储在 gcs 中的文件。我还需要实现重命名文件夹。该客户端库没有任何重命名方法。 所以,我要做的是,1.创建一个新文件夹。 2.将旧文件夹的所有内容复制到较新的文件夹中。 3.删除旧文件夹。但这似乎是一个漫长的过程..【参考方案2】:

https://cloud.google.com/storage/docs/gsutil/addlhelp/WildcardNames

gsutil 支持 URI 通配符

编辑

gsutil 3.0 release note

作为桶子目录支持的一部分,我们将 * 通配符更改为仅匹配目录边界,并引入了新的 ** 通配符...

bucket 下有目录吗?如果是这样,也许您需要深入到每个目录或使用**。

gsutil -m mv gs://my_bucket/**.JPG gs://my_bucket/**.jpg

gsutil -m mv gs://my_bucket/mydir/*.JPG gs://my_bucket/mydir/*.jpg

编辑 到目前为止,gsutil 不支持目标通配符(截至 2014 年 4 月 12 日) 下界API。

所以此时您需要检索所有 JPG 文件的列表, 并重命名每个文件。

python 示例:

import subprocess
files = subprocess.check_output("gsutil ls gs://my_bucket/*.JPG",shell=True)
files = files.split("\n")[:-1]
for f in files:
    subprocess.call("gsutil mv %s %s"%(f,f[:-3]+"jpg"),shell=True)

请注意,这需要几个小时。

【讨论】:

嗯似乎不起作用,出现“CommandException:目标(gs://my_bucket/*.jpg)必须完全匹配 1 个 URL” 我编辑了 :) 抱歉我现在没有环境可以测试,如果不行我会测试一些其他方法 不,目录是正确的。我认为问题在于它不进行通配符替换? 确实不行。看来你必须在检索文件列表后一一重命名,甚至效率低下..而且GCS API似乎没有复制/重命名功能..【参考方案3】:

这是在 bash 中执行此操作的本机方法,下面逐行解释代码:

gsutil ls gs://bucket_name/*.JPG > src-rename-list.txt
sed 's/\.JPG/\.jpg/g' src-rename-list.txt > dest-rename-list.txt
paste -d ' ' src-rename-list.txt dest-rename-list.txt | sed -e 's/^/gsutil\ mv\ /' | while read line; do bash -c "$line"; done
rm src-rename-list.txt; rm dest-rename-list.txt

解决方案推送 2 个列表,一个用于源文件,一个用于目标文件(用于“gsutil mv”命令):

gsutil ls gs://bucket_name/*.JPG > src-rename-list.txt
sed 's/\.JPG/\.jpg/g' src-rename-list.txt > dest-rename-list.txt

使用以下代码将“gsutil mv”行和两个文件逐行连接起来:

paste -d ' ' src-rename-list.txt dest-rename-list.txt | sed -e 's/^/gsutil\ mv\ /'

然后在 while 循环中运行每一行: 而读线;做 bash -c "$line";完成

最后,清理并删除创建的文件:

rm src-rename-list.txt; rm dest-rename-list.txt

以上内容已针对工作中的 Google Storage 存储分区进行了测试。

【讨论】:

喜欢这个解决方案,只有小评论,而不是:gsutil ls gs://bucket_name/*.JPG | sed 's/\.JPG/\.jpg/g' > dest-rename-list.txt 简化为: cat src-rename-list.txt | sed 's/\.JPG/\.jpg/g' > dest-rename-list.txt【参考方案4】:

gsutil 不支持并行化和批量复制/重命名。

你有两个选择:

使用数据流进程执行操作 或 使用 GNU 并行使用多个进程启动它

如果您使用 GNU Parallel,最好部署一个新实例来进行批量复制/重命名操作:

首先: - 列出要复制/重命名的文件(源和目标由空格或制表符分隔的文件),如下所示:
gs://origin_bucket/path/file gs://dest_bucket/new_path/new_filename
第二步:启动一个新的计算实例 第三:在该实例中登录并安装 Gnu 并行
sudo apt install parallel
第三:授权自己使用 google(gcloud auth login),因为用于计算的服务帐户可能无权移动/重命名文件。
gcloud auth login
使用并行进行复制 (gsutil cp) 或移动 (gsutil mv) 操作:
   parallel -j 20 --colsep ' ' gsutil mv 1 2 :::: file_with_source_destination_uris.txt

这将使 gsutil cp 操作并行运行 20 次。

【讨论】:

以上是关于在 Google Cloud Storage 上批量重命名对象的主要内容,如果未能解决你的问题,请参考以下文章

ReferenceError:导入@google-cloud/storage 时分配的左侧无效

错误:模块“google.cloud.bigquery_storage”没有属性“BigQueryReadClient”

使用 Cloud Functions for Firebase 和 @google-cloud/storage 删除图像时出现问题

google cloud storage托管静态页面

Google Cloud Platform:无法通过API在Storage中上传新文件版本

使用 Google Endpoints 在 Google Cloud Storage 上上传图片