Zip

解壓目錄的一部分?

  • August 8, 2013

一個 zipfilef.zip包含一堆帶有目錄的文件。

A/B
A/B/C
A/B/C/D

..
A/B/C/D/and/some/more/dirs
A/B2

現在我只對 C/D 下面的樹感興趣。我可以將unzip f.zip */D/* -d .D 下的所有內容(假設 D 是唯一序列)解壓縮到目前目錄,包括 A/B/C,但是我希望 D 成為我解壓縮操作的根目錄。當然,我可以將 D 移動到我目前的工作目錄,但我認為這是作弊。

手冊頁和Google確實揭示了一個解決方案,但也許我忽略了,也許有比移動更好的解決方案。

哦,我的平台是 mac os x 10.8.prettyup2date

通過解壓縮手冊頁:

  -j     junk paths.  The archive's directory structure is not recreated;
    all files are deposited in the extraction directory (by default,
    the current one).

所以:

unzip -d D -j f.zip */D/*

將其全部提取到名為 D 的文件夾中,但沒有目錄結構(注意,這會將 D 的子目錄中的文件提取到頂級輸出 D 文件夾中)。

EDIT OP 希望將文件結構保留在 D 文件夾下。

unzip -l f.zip | grep 'A/B/C/D' | \
perl -ple 's/\s+\d+\s+\d{4}-\d{2}-\d{2}\s+\d{2}:\d{2}\s+(.*)$/$1/' | \
while read file
do 
   unzip -j -d "$(echo $file | sed 's:A/B/C/\(.*\)/.*:\1:g')" f.zip "$file"
done

每個步驟的部分:

unzip -l f.zip

獲取 f.zip 中的文件列表

grep 'A/B/C/D'

grep 顯示目標目錄下的文件的行

perl -ple 's/\s+\d+\s+\d{4}-\d{2}-\d{2}\s+\d{2}:\d{2}\s+(.*)$/$1/'

使用 perl 獲取匹配行上的文件名(我的 sed-fu 不如 Stephane 的那麼好,所以我將使用 perl!),注意這處理文件名中的空格:)

while read file
do

循環通過上述命令生成的文件並將其分配給$file

unzip -j -d "$(echo $file | sed 's:A/B/C/\(.*\)/.*:\1:g')" f.zip "$file" 

將目標解壓縮$file,將其路徑丟棄到目標目錄

echo $file | sed 's:A/B/C/\(.*\)/.*:\1:g'

從文件名中刪除前導 A/B/C/ 路徑,請注意它包含在 $() 中(a Command substitution,有關更多詳細資訊,請參見 bash )並且命令替換在雙引號內以保留空格(並實際評估$())。

done

完成循環。

這實際上為 A/B/C 下匹配的每個文件執行解壓縮操作:

unzip -j -d "D" f.zip "A/B/C/D/"
unzip -j -d "D" f.zip "A/B/C/D/b"
unzip -j -d "D" f.zip "A/B/C/D/e"
unzip -j -d "D/stupid space" f.zip "A/B/C/D/stupid space/"
unzip -j -d "D/stupid space" f.zip "A/B/C/D/stupid space/b"
unzip -j -d "D/stupid space" f.zip "A/B/C/D/stupid space/e"
unzip -j -d "D/stupid space" f.zip "A/B/C/D/stupid space/d"
unzip -j -d "D/stupid space" f.zip "A/B/C/D/stupid space/c"
unzip -j -d "D/stupid space" f.zip "A/B/C/D/stupid space/a"
unzip -j -d "D" f.zip "A/B/C/D/d"
unzip -j -d "D" f.zip "A/B/C/D/f"

-o如果您執行此命令以提取到已經存在的文件結構中,您將需要在現有文件中添加額外override的內容(或者第一個會破壞文件的解壓縮操作會提示 areplace D/b? [y]es, [n]o, [A]ll, [N]one, [r]ename: extracting: D/b然後將其彈出)。如果您需要該提示,那麼您將不得不使用另一種不使用 read 並且處理空格的循環方法(for $( ... )該測試將失敗)。如果你需要這樣做,我會把它作為練習留給你鍛煉!

引用自:https://unix.stackexchange.com/questions/85797