第一经济网欢迎您!
当前位置:首页>综合 > 正文内容

天天视讯!S3 对象重命名


【资料图】

本文所述操作适用于兼容 S3 协议的所有存储框架,包括 AWS S3Aliyun OSSMinIOCeph等。

不知为何,截止目前,S3 协议并不包含对象重命名的接口。如果有重命名对象的需求,一般能想到的就是重新上传改名之后的对象,然后从存储桶中将原名对象删除。很明显,这种方式好比大炮打蚊子,目的达到了,累得一身汗,要是本地没有备份,还得先下载,费时费力费钱。特别是当待处理的对象的数量相当庞大的时候,如果不想持续加班一个月,那就要琢磨琢磨另辟蹊径才行。

能不能将存储桶挂载到本地,然后用本地 shell 命令操作其中的对象呢?值得一试!

挂载

使用 rclones3fs-fusegoofys等工具挂载,这里以 goofys 为例。

直接下载编译好的执行文件wget https://github.com/kahing/goofys/releases/latest/download/goofys设置执行权限chmod +x goofysS3 密钥配置
mkdir ~/.awsvi ~/.aws/credentials# 以下是 ~/.aws/credentials 内容[default]aws_access_key_id = xxxxxxxaws_secret_access_key = yyyyyyyy
创建挂载点mkdir /mnt/foo挂载
mkdir /opt/goofys./goofys --endpoint https://us-east.s3.aws.com bucketName /mnt/foo/
验证是否挂载成功。
# 列出前 10 个文件ls /mnt/foo/ | head -n 10# 注意:该语句并不能减少 ls 的执行时间。当文件数量过多时,可以使用通配符减少 ls 的罗列数量。
重命名

挂载成功之后,我们就可以采用 mvrename指令尝试重命名文件了,下面以 perl 版本的 rename 为例(该版本支持正则表达式)。

# 所有文件名只保留后 5 个字符,并更改扩展名rename "s/\w*?(\w{5})\.mdi/$1.obj/" *# 实际也是逐个文件处理,而非一次性同时处理,文件多则耗时# 如果文件太多则会报 "Argument list too long"(虽然参数只有一个星号,但实则是将所有文件名查找出来后执行),可以改成如下方式:find . -name "*" | xargs rename "s/\w*?(\w{5})\.mdi/$1.obj/"# 虽然不会报错,但其实只是将查找文件名环节转给了 find,总耗时是一样的

为了更好更灵活地重命名巨量文件,只能编写脚本了。以下是示例代码:

rename_s3_objects(){local renamedCnt=0for obj in ./*dorename "s/\w*?(\w{5})\.mdi/$1.obj/" $objrenamedCnt=$(($renamedCnt + 1))if [ `expr $renamedCnt % 100` -eq 0 ]; then                # 每处理完 100 个对象就输出提示echo "$renamedCnt objects renamed"fidonereturn 0}rename_s3_objects# 似乎 ``; $[]; $(()) 都可以执行运算

保存后,在命令行中使用 sh saved_file_name执行即可。

经测算,在普通网络环境下,每重命名 100 个对象(大约 100M),耗时 70s 左右。并未检查过程中是否涉及到对象的传输(博主试验的服务器并没有带宽使用数据),推测应该是没有,有兴趣的朋友可以验证下。

除重命名外,类似于[批量]删除、创建文件夹( S3 中对象加斜杠前缀)等指令应该也可以通过挂载方式玩转。

关键词:

标签阅读


}