2014-03-25 101 views
0

我在Linux環境中使用gsutil來管理GCS中的文件。我喜歡能夠使用命令使用STDIN的「gsutil rm」命令

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

前面有一些其他命令將STDIN傳遞給gsutil以上傳文件;這樣做,我可以維護已上傳的文件的本地列表,或生成特定的模式以上傳並交付。

我希望能夠做一個類似的命令一樣

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

以同樣擦洗文件。目前,我建立文件的大名單刪除並運行它用下面的代碼:

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

相比,多線程這是非常慢「的gsutil -m RM ...」命令,使-m當您必須從列表中逐個處理文件時,標誌不起作用。我也嘗試過正在運行

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

但這涉及重新複製大量數據並浪費大量時間;數據已經存在,只需要刪除一些。任何想法將不勝感激。另外,在重命名文件方面,我沒有太大的靈活性。否則,上傳前的快速重命名將處理所有這些。

回答

3

作爲過渡方案,因爲我們沒有爲rm一個-I選項,現在,如何只創建所有你想在循環中刪除對象的字符串,然後使用gsutil -m rm刪除嗎?你也可以用一個簡單的python腳本來做到這一點,該腳本從python內部調用gsutil命令作爲一個單獨的過程。

擴大對你剛纔的例子,也許類似如下(聲明:我的bash福是不是最大的,而我沒有測試過這一點):

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

閱讀'gsutil rm'的文檔頁面並沒有顯示任何有關可以像這樣的多個項目重載的內容,但是我會盡快對它進行測試!如果這有效,那麼你剛剛解決了我的問題。謝謝@Zach Wilt – user3461099

+0

提供這樣的參數列表應該工作。在rm幫助文檔的概要部分中,我們將模板列爲'gsutil rm [-f] [-R] url ...',這意味着您可以在其中提供任意數量的url。 這不是特別清楚的imo,所以我們應該考慮一個更明顯的方式在文檔中調用它。 –

+0

工作就像一個魅力;我會爲下面的任何人提供一個更強大的示例,但如果可以的話,我會將答案標記爲答案(對StackOverflow的系統還不熟悉)。謝謝@Zach Wilt。 – user3461099

0

大家很奇怪,我咬咬牙像上面指出的Zach Wilt一樣。作爲參考,我從5個目錄中抽取了幾千個文件,大約有10,000個文件。如果沒有「-m」開關,則需要花費30分鐘以上;與「-m」開關,它需要不到30秒。放大!

一個可靠的例子:我使用它來更新Google Cloud Storage文件以匹配本地文件。在當天,我有一個程序可以轉儲大量增量文件,也是一小部分「滾動」的文件。一週後,增量文件會自動在本地清理,但在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 

你需要修改,以適應您的需求,但這是局部刪除文件,然後同步改變谷歌雲存儲的具體和工作方法。顯然,修改以適應您的需求。再次感謝@ Zach Wilt。