如何判斷“解壓縮”是否會提前創建一個文件夾?
一個常見的場景是在一個目錄中有一個 zip 文件和其他工作:
me@work ~/my_working_folder $ ls downloaded.zip workfile1 workfile2 workfile3
我想解壓縮
downloaded.zip
,但我不知道它是否會弄得一團糟,或者它是否很好地創建了自己的目錄。我正在進行的解決方法是創建一個臨時文件夾並在那裡解壓縮:me@work ~/my_working_folder $ mkdir temp && cp downloaded.zip temp && cd temp me@work ~/my_working_folder/temp $ ls downloaded.zip me@work ~/my_working_folder/temp $ unzip downloaded.zip Archive: downloaded.zip creating: nice_folder/
這可以防止
my_working_folder
填充大量 zip 文件內容。我的問題是:有沒有更好的方法來確定一個 zip 文件在解壓縮之前是否只包含一個文件夾?
從手冊…
$$ -d exdir $$ 提取文件的可選目錄。預設情況下,所有文件和子目錄都在目前目錄中重新創建;-d 選項允許在任意目錄中提取(總是假設一個人有權寫入該目錄)。這個選項不需要出現在命令行的末尾;它也可以在 zipfile 規範之前(使用普通選項)、在 zipfile 規範之後或在文件和 -x 選項之間接受。選項和目錄可以連接在一起,它們之間沒有任何空格,但請注意,這可能會導致正常的 shell 行為被抑制。特別是,
-d ~
(波浪號)由 Unix C shell 擴展為使用者主目錄的名稱,但-d~
被視為文字子目錄~
目前目錄的。所以…
unzip -d new_dir zipfile.zip
這將創建一個目錄 new_dir,並在其中提取檔案,這樣即使不先查看也可以避免每次都可能造成的混亂。看看也很有用
man unzip
。手冊頁的更多幫助。
好吧,如果它最終只包含一個項目,你可以無條件地提取到一個子目錄中並在之後刪除它。
但是,當您可以使用時,為什麼要選擇一個理智而簡單的解決方案(由ilkkachu
awk
提供) ?:)sunzip () { if [ $# -ne 1 ] || ! [ -f "$1" ] then printf '%s\n' "Expected a filename as the first (and only) argument. Aborting." return 1 fi extract_dir="." # Strip the leading and trailing information about the zip file (leaving # only the lines with filenames), then check to make sure *all* filenames # contain a /. # If any file doesn't contain a / (i.e. is not located in a directory or is # a directory itself), exit with a failure code to trigger creating a new # directory for the extraction. if ! unzip -l "$1" | tail -n +4 | head -n -2 | awk 'BEGIN {lastprefix = ""} {if (match($4, /[^/]+/)) {prefix=substr($4, RSTART, RLENGTH); if (lastprefix != "" && prefix != lastprefix) {exit 1}; lastprefix=prefix}}' then extract_dir="${1%.zip}" fi unzip -d "$extract_dir" "$1" }
快不髒。適用於 InfoZIP 的
unzip
v6.0。您可能希望根據您的需要調整它,例如接受或自動使用附加參數
unzip
,或者為提取子目錄使用不同的名稱(目前由zip
文件名確定)。哦,我剛剛注意到此解決方法正確處理了兩種最常見的情況(1. ZIP 文件包含一個包含內容的目錄,2. ZIP 文件包含許多單獨的文件和/或目錄),但不會創建當 ZIP 文件的根目錄包含多個目錄但沒有文件時的子目錄…
**編輯:**固定。該
awk
腳本現在儲存 ZIP 文件中包含的每個路徑的第一個組件(“前綴”),並在檢測到與前一個不同的前綴時中止。這會同時擷取多個文件和多個目錄(因為兩者都必須具有不同的名稱),同時忽略所有內容都包含在同一子目錄中的 ZIP 文件。