使用STDIN的“gsutil rm”命令

时间:2014-03-25 18:26:10

标签: python linux google-cloud-storage gsutil

我在Linux环境中使用gsutil来管理GCS中的文件。我喜欢能够使用命令

gsutil -m cp -I gs://...

之前有一些其他命令将STDIN传递给gsutil以上传文件;在这样做的过程中,我可以维护一个已上传的文件的本地列表,或者生成要上传的特定模式并将其移除。

我希望能够像

那样执行类似的命令
gsutil -m rm -I gs://...

以类似方式擦除文件。目前,我构建了一个要删除的大文件列表,并使用以下代码运行它:

while read line
do
gsutil rm gs://...
done < "$myfile.txt"

与多线程&#34; gsutil -m rm相比,这是非常慢的...&#34;命令,并且当您必须从列表中一次处理一个文件时,启用-m标志无效。我也尝试过运行

gsutil -m rm gs://.../* # remove everything
<my command> | gsutil -m cp -I gs://.../ # put back the pieces that I want

但这涉及重新复制大量数据并浪费大量时间;数据已经存在,只需要删除一些。任何想法将不胜感激。另外,我在重定位文件的两端都没有很大的灵活性;否则,在上传之前快速重命名将处理所有这些。

2 个答案:

答案 0 :(得分:3)

作为临时解决方案,由于我们现在没有为-I提供rm选项,如何在循环中创建要删除的所有对象的字符串,然后使用gsutil -m rm删除它?您也可以使用一个简单的python脚本来执行此操作,该脚本在python中作为单独的进程调用gsutil命令。

扩展您之前的示例,可能类似于以下内容(免责声明:我的bash-fu不是最好的,我还没有对此进行测试):

objects=''
while read line
do
  objects="$objects gs://$line"
done
gsutil -m rm $objects

答案 1 :(得分:1)

对于任何想知道的人,我都像上面所说的Zach Wilt一样。作为参考,我从5个目录的范围中删除了几千个文件的顺序,因此大约有10,000个文件。没有“-m”开关这样做需要花费30分钟;使用“-m”开关,只需不到30秒。放大!

有一个强有力的示例:我使用它来更新Google云端存储文件以匹配本地文件。在当天,我有一个程序可以转储大量增量的文件,还有一些“卷起”的文件。一周后,增量文件会自动在本地清理,但在GCS中也应该这样做以节省空间。以下是如何执行此操作:

#!/bin/bash

# get the full date strings for touch
start=`date --date='-9 days' +%x`
end=`date --date='-8 days' +%x`

# other vars
mon=`date --date='-9 days' +%b | tr [A-Z] [a-z]`
day=`date --date='-9 days' +%d`

# display start and finish times
echo "Cleaning files from $start"

# update start and finish times
touch --date="$start" /tmp/start1
touch --date="$end" /tmp/end1

# repeat for all servers
for dr in "dir1" "dir2" "dir3" ... 
do

    # list files in range and build retention file
    find /local/path/$dr/ -newer /tmp/start1 ! -newer /tmp/end1 > "$dr-local.txt"

    # get list of all files from appropriate folder on GCS
    gsutil ls gs://gcs_path/$mon/$dr/$day/ > "$dr-gcs.txt"

    # formatting the host list file
    sed -i "s|gs://gcs_path/$mon/$dr/$day/|/local/path/$dr/|" "$dr-gcs.txt"

    # build sed command file to delete matches
    while read line
    do
        echo "\|$line|d" >> "$dr-del.txt"
    done < "$dr-local.txt"

    # run command file to strip lines for files that need to remain
    sed -f "$dr-del.txt" <"$dr-gcs.txt" >"$dr-out.txt"

    # convert local names to GCS names
    sed -i "s|/local/path/$dr/|gs://gcs_path/$mon/$dr/$day/|" "$dr-out.txt"

    # new variable to hold string
    del=""

    # convert newline separated file to one long string
    while read line
    do
        del="$del$line "
    done < "$dr-out.txt"

    # remove all files matching the final output
    gsutil -m rm $del

    # cleanup files
    rm $dr-local.txt
    rm $dr-gcs.txt
    rm $dr-del.txt
    rm $dr-out.txt

done

您需要进行修改以满足您的需求,但这是一种在本地删除文件,然后将更改同步到Google云端存储的具体方法。显然,修改以满足您的需求。再次感谢@Zach Wilt。