使用 gsutil 移动多个文件
Moving multiple files with gsutil
假设我在 Google 云存储桶中有以下文件:
file_A1.csv
file_B2.csv
file_C3.csv
现在我想移动这些文件的一个子集,比方说 file_A1.csv
和 file_B2.csv
。目前我是这样做的:
gsutil mv gs://bucket/file_A1.csv gs://bucket/file_A11.csv
gsutil mv gs://bucket/file_B2.csv gs://bucket/file_B22.csv
这种方法需要两次调用或多或少相同的命令,并分别移动每个文件。我知道,如果我移动一个完整的目录,我可以添加 -m
选项来加速这个过程。但是,不幸的是,我只想移动所有文件的一个子集,而将其余文件保留在存储桶中。
以这种方式移动 100 个文件时,我需要执行 100 条左右的命令,这变得非常耗时。我有一种方法可以将 100 个文件中的每一个文件合并到一个命令中,另外还有 -m
选项?
gsutil 目前不支持此功能,但您可以创建多个 shell 脚本,每个脚本执行一部分移动,然后 运行 它们同时执行。
请注意 gsutil mv is based on the syntax of the unix mv command,它也不支持您要求的功能。
如果您有要移动的文件列表,可以使用-I
option from the cp
command which, according to the docs,对mv
命令也有效:
cat filelist | gsutil -m mv -I gs://my-bucket
您可以使用 bash 通过遍历 gsutil ls
输出来实现,例如:
- 源文件夹名称:
old_folder
- 新文件夹名称:
new_folder
for x in `gsutil ls "gs://<bucket_name>/old_folder"`; do y=$(basename -- "$x");gsutil mv ${x} gs://<bucket_name>/new_folder/${y}; done
缺少-m
标志是这里真正的挂断。面对同样的问题,我最初通过使用 python 多处理和 os.system
来调用 gsutil 来解决这个问题。我有 60k 个文件,这需要几个小时。通过一些实验,我发现使用 python 客户端可以提高 20 倍的速度!
如果您愿意离开 gsutil
- 这是更好的方法。
这是一个复制(或移动)方法。如果您创建一个 src keys/uri 的列表,您可以使用多线程调用它以获得快速结果。
注意:该方法是一个 (destination-name,exception) 的元组,您可以将其弹出到数据框或其他东西中以查找故障
def cp_blob(key=None,bucket=BUCKET_NAME,uri=None,delete_src=False):
try:
if uri:
uri=re.sub('gs://','',uri)
bucket,key=uri.split('/',maxsplit=1)
client=storage.Client()
bucket=client.get_bucket(bucket)
blob=bucket.blob(key)
dest=re.sub(THING1,THING2,blob.name) ## OR SOME OTHER WAY TO GET NEW DESTINATIONS
out=bucket.copy_blob(blob,bucket,dest)
if delete_src:
blob.delete()
return out.name, None
except Exception as e:
return None, str(e)
要做到这一点,您可以运行遵循 gsutil 命令:
gsutil mv gs://bucket_name/common_file_name* gs://bucket_destiny_name/common_file_name*
在你的情况下; common_file_name 是“file_”
假设我在 Google 云存储桶中有以下文件:
file_A1.csv
file_B2.csv
file_C3.csv
现在我想移动这些文件的一个子集,比方说 file_A1.csv
和 file_B2.csv
。目前我是这样做的:
gsutil mv gs://bucket/file_A1.csv gs://bucket/file_A11.csv
gsutil mv gs://bucket/file_B2.csv gs://bucket/file_B22.csv
这种方法需要两次调用或多或少相同的命令,并分别移动每个文件。我知道,如果我移动一个完整的目录,我可以添加 -m
选项来加速这个过程。但是,不幸的是,我只想移动所有文件的一个子集,而将其余文件保留在存储桶中。
以这种方式移动 100 个文件时,我需要执行 100 条左右的命令,这变得非常耗时。我有一种方法可以将 100 个文件中的每一个文件合并到一个命令中,另外还有 -m
选项?
gsutil 目前不支持此功能,但您可以创建多个 shell 脚本,每个脚本执行一部分移动,然后 运行 它们同时执行。
请注意 gsutil mv is based on the syntax of the unix mv command,它也不支持您要求的功能。
如果您有要移动的文件列表,可以使用-I
option from the cp
command which, according to the docs,对mv
命令也有效:
cat filelist | gsutil -m mv -I gs://my-bucket
您可以使用 bash 通过遍历 gsutil ls
输出来实现,例如:
- 源文件夹名称:
old_folder
- 新文件夹名称:
new_folder
for x in `gsutil ls "gs://<bucket_name>/old_folder"`; do y=$(basename -- "$x");gsutil mv ${x} gs://<bucket_name>/new_folder/${y}; done
缺少-m
标志是这里真正的挂断。面对同样的问题,我最初通过使用 python 多处理和 os.system
来调用 gsutil 来解决这个问题。我有 60k 个文件,这需要几个小时。通过一些实验,我发现使用 python 客户端可以提高 20 倍的速度!
如果您愿意离开 gsutil
- 这是更好的方法。
这是一个复制(或移动)方法。如果您创建一个 src keys/uri 的列表,您可以使用多线程调用它以获得快速结果。
注意:该方法是一个 (destination-name,exception) 的元组,您可以将其弹出到数据框或其他东西中以查找故障
def cp_blob(key=None,bucket=BUCKET_NAME,uri=None,delete_src=False):
try:
if uri:
uri=re.sub('gs://','',uri)
bucket,key=uri.split('/',maxsplit=1)
client=storage.Client()
bucket=client.get_bucket(bucket)
blob=bucket.blob(key)
dest=re.sub(THING1,THING2,blob.name) ## OR SOME OTHER WAY TO GET NEW DESTINATIONS
out=bucket.copy_blob(blob,bucket,dest)
if delete_src:
blob.delete()
return out.name, None
except Exception as e:
return None, str(e)
要做到这一点,您可以运行遵循 gsutil 命令:
gsutil mv gs://bucket_name/common_file_name* gs://bucket_destiny_name/common_file_name*
在你的情况下; common_file_name 是“file_”