2008-09-20 66 views
43

unzip命令沒有用於遞歸解壓縮檔案的選項。如何從Unix命令行遞歸地解壓目錄及其子目錄中的歸檔文件?

如果我有以下目錄結構和檔案:

 
/Mother/Loving.zip 
/Scurvy/Sea Dogs.zip 
/Scurvy/Cures/Limes.zip 

,我想所有的檔案解壓縮到目錄具有相同的名稱爲每個存檔:

 
/Mother/Loving/1.txt 
/Mother/Loving.zip 
/Scurvy/Sea Dogs/2.txt 
/Scurvy/Sea Dogs.zip 
/Scurvy/Cures/Limes/3.txt 
/Scurvy/Cures/Limes.zip 

什麼命令或命令我會問嗎?

,這不會對在他們空格的文件名嗆這一點很重要。

+0

如何處理長文件路徑...超過260個字符...:https://superuser.com/a/1263234/439537 – Andrew 2017-10-28 06:13:49

回答

59

如果你想將文件解壓到相應的文件夾,你可以試試這個

find . -name "*.zip" | while read filename; do unzip -o -d "`dirname "$filename"`" "$filename"; done; 

多處理版本系統,可以處理高I/O:

find . -name "*.zip" | xargs -P 5 -I fileName sh -c 'unzip -o -d "$(dirname "fileName")/$(basename -s .zip "fileName")" "fileName"' 
29

這裏有一個解決方案,包括find命令和while循環:

find . -name "*.zip" | while read filename; do unzip -o -d "`basename -s .zip "$filename"`" "$filename"; done; 
+3

**注意** - 將所有zip文件解壓縮到**工作目錄!**而您請求相對解壓縮。看到[Vivek的答案](http://stackoverflow.com/a/2318189/3191896) – 2015-03-04 08:11:31

+0

嗯,它似乎並沒有提取他們所有的工作目錄AFAICT。我使用OS X El Capitan 10.11.6的UnZip 5.52。結果似乎與Vivek相同。儘管接受他的回答,因爲它也展示瞭如何利用多核心! – chuckrector 2016-10-09 00:36:26

2

喜歡的東西使用-r標誌gunzip解....

旅遊目錄結構遞歸?如果命令行中指定的任何文件名都是目錄,則gzip將下載到該目錄中並壓縮它在其中找到的所有文件(或在gunzip中解壓縮它們)。

http://www.computerhope.com/unix/gzip.htm

+2

他特別談論zip文件,而不是gzip文件。 – dvorak 2008-09-20 14:16:26

4

你可以使用帶有-exec標誌找到沿着一個命令行做

find . -name "*.zip" -exec unzip {} \; 
+0

這將所有內容解壓到當前目錄,而不是相對於每個子目錄。它也不會解壓縮到與每個存檔相同名稱的目錄中。 – chuckrector 2008-09-20 12:31:52

0

如果你使用Cygwin的工作,語法是基本名稱略有不同命令。

find . -name "*.zip" | while read filename; do unzip -o -d "`basename "$filename" .zip`" "$filename"; done; 
0

我意識到這是很老,但它是在谷歌的第一個命中的時候我一直在尋找一個解決類似的東西之一,所以我會後我做了什麼在這裏。我的情況是,我基本上只是想充分爆炸罐,以包含的所有罐子一起略有不同,所以我寫了下面的bash功能:

function explode { 
    local target="$1" 
    echo "Exploding $target." 
    if [ -f "$target" ] ; then 
     explodeFile "$target" 
    elif [ -d "$target" ] ; then 
     while [ "$(find "$target" -type f -regextype posix-egrep -iregex ".*\.(zip|jar|ear|war|sar)")" != "" ] ; do 
      find "$target" -type f -regextype posix-egrep -iregex ".*\.(zip|jar|ear|war|sar)" -exec bash -c 'source "<file-where-this-function-is-stored>" ; explode "{}"' \; 
     done 
    else 
     echo "Could not find $target." 
    fi 
} 

function explodeFile { 
    local target="$1" 
    echo "Exploding file $target." 
    mv "$target" "$target.tmp" 
    unzip -q "$target.tmp" -d "$target" 
    rm "$target.tmp" 
} 

注意,如果你存儲所需要的<file-where-this-function-is-stored>這在一個文件中,我沒有爲非交互式shell讀取,就像我碰巧那樣。如果你存儲在裝載於在非交互shell文件的功能(例如,.bashrc我相信)你可以將整個source聲明。希望這會幫助某人。

一個小警告 - explodeFile也刪除ziped文件,你當然可以改變的,通過註釋掉的最後一行。

10

正確處理所有的文件名(包括新行),並提取到一個目錄是在相同的位置的文件,只是擴展除去溶液中:

find . -name '*.zip' -exec sh -c 'unzip -o -d "${0%.*}" "$0"' '{}' ';' 

請注意,您可以輕鬆地進行

find . '(' -name '*.zip' -o -name '*.jar' ')' -exec ... 
0

另一個有趣的解決辦法是:

它通過添加他們使用 -o,例如處理更多的文件類型(例如 .jar) 0
DESTINY=[Give the output that you intend] 

# Don't forget to change from .ZIP to .zip. 
# In my case the files were in .ZIP. 
# The echo were for debug purpose. 

find . -name "*.ZIP" | while read filename; do 
ADDRESS=$filename 
#echo "Address: $ADDRESS" 
BASENAME=`basename $filename .ZIP` 
#echo "Basename: $BASENAME" 
unzip -d "$DESTINY$BASENAME" "$ADDRESS"; 
done; 
相關問題