नेस्टेड ज़िप फ़ाइलों को निकालना


15

मेरे पास कई ज़िप अभिलेखागार हैं, जिनमें से प्रत्येक में कई ज़िप अभिलेखागार हैं। इस ज़िप आर्काइव और इसके चाइल्ड जिप आर्काइव्स के भीतर मौजूद सभी फाइलों को फिर से निकालने का सबसे अच्छा तरीका क्या है, जो खुद जिप आर्काइव नहीं हैं?


आप उन चीजों को निकालने से क्या मतलब है जो ज़िप फाइलें नहीं हैं? आप उन्हें दूसरी जगह कॉपी करना चाहते हैं?
12

मुझे आपकी आवश्यकताएं स्पष्ट नहीं लगतीं। मुझे शॉन जे। गोफ और मेरी व्याख्या समान रूप से लगती है। क्या आप स्पष्ट कर सकते हैं?
गाइल्स का SO- 13

@ गिल्स: सॉरी, हाँ यह थोड़ा अस्पष्ट था। मैंने इसे थोड़ा बदल दिया, उम्मीद है कि अब यह और स्पष्ट हो जाएगा।
ओडाम्स

मैं एक उत्तर पोस्ट करने जा रहा था, लेकिन मेरा मानना ​​है कि इसे एक टिप्पणी के रूप में जाना चाहिए: नेस्टेड अभिलेखागार आपके लिए आवश्यक स्थान को बढ़ाते हैं ! आप शायद ज़िप फ़ाइल प्रारूप का मतलब है, सिर्फ gzip नहीं। हर ज़िप फ़ाइल पहले से ही संपीड़ित होती है, उन्हें फिर से संपीड़ित करता है, बस अधिक उपरि बनाता है, प्रभावी रूप से आवश्यक स्थान को बढ़ाता है।
पोलीमोन

हाँ, मैंने ऐसा नहीं किया: पी। दुर्भाग्य से मैं फ़ाइलों को वितरित करने के इस विचित्र तरीके के अधीन हूं।
oadams 5

जवाबों:


13

यह वर्तमान निर्देशिका में सभी ज़िप फ़ाइलों को निकालेगा, उनके भीतर मौजूद किसी भी zipfiles को छोड़कर।

find . -type f -name '*.zip' -exec unzip -- '{}' -x '*.zip' \;

यद्यपि यह सामग्री को वर्तमान निर्देशिका में निकालता है, लेकिन सभी फाइलें इस निर्देशिका में सख्ती से समाप्त नहीं होंगी क्योंकि सामग्री में उपनिर्देशिका शामिल हो सकती है।

यदि आप वास्तव में वर्तमान निर्देशिका में सभी फ़ाइलों को सख्ती से चाहते थे, तो आप चला सकते हैं

find . -type f -mindepth 2 -exec mv -- '{}' . \;

नोट: यदि विभिन्न निर्देशिकाओं में एक ही नाम के साथ दो हैं तो यह क्लॉबर फाइल करेगा।

यदि आप सभी ज़िप फ़ाइलों और भीतर मौजूद ज़िपों को पुन: निकालना चाहते हैं, तो निम्न वर्तमान निर्देशिका में सभी ज़िप फ़ाइलों को निकालता है और सभी ज़िपों को वर्तमान निर्देशिका में समाहित करता है।

while [ "`find . -type f -name '*.zip' | wc -l`" -gt 0 ]
do
    find . -type f -name "*.zip" -exec unzip -- '{}' \; -exec rm -- '{}' \;
done

यह जबकि पाश ने मुझे एक एथिकल हैकिंग प्रतियोगिता में बहुत मदद की, जहां उन्होंने 31337 के स्तर पर जाने वाली नेस्टेड ज़िप फ़ाइल तैयार की थी, धन्यवाद!
पेड़ी

2
आपको यह वैरिएंट पसंद आ सकता है, जिसका उपयोग मैं नेस्टेड ईयर, वॉर, जार फाइल्स से कॉन्ट्रैक्टली एक्सट्रैक्ट करने के लिए करता हूं : gist.github.com/tyrcho/479c18795d997c201e53 मेजर अंतर यह है कि यह प्रत्येक आर्काइव के लिए नेस्टेड फोल्डर बनाता है। while [ "खोजो। -Type f -name '*।? ar?' | wc -l" -gt 0 ]; do find -type f -name "*.?ar" -exec mkdir -p '{}.dir' \; -exec unzip -d '{}.dir' -- '../{}' \; -exec rm -- '{}' \;; done
Michel में मिशेल दावोट

4

जहाँ तक मैं समझता हूँ, आपके पास ज़िप अभिलेखागार हैं जो स्वयं ज़िप अभिलेखागार में हैं, और जब भी किसी को निकाला जाता है, तो आप नेस्टेड ज़िप को अनज़िप करना चाहेंगे।

यहाँ एक bash 4 स्क्रिप्ट है जो सभी ज़िप को वर्तमान निर्देशिका और इसके उपनिर्देशिकाओं को पुन: खोल देता है, प्रत्येक ज़िप फ़ाइल को हटाए जाने के बाद हटा देता है, और जब तक ज़िप फ़ाइलें हैं तब तक जाती रहती है। एक उपनिर्देशिका में एक जिप फाइल को उस उपनिर्देशिका के सापेक्ष निकाला जाता है। चेतावनी: अनटाइटेड, इसे आज़माने से पहले मूल फ़ाइलों का बैकअप बना लें या डायरेक्टरी ट्री के बाहरrm ज़िप फ़ाइल को ले जाकर बदल दें ।

shopt -s globstar nullglob
while set -- **/*.zip; [ $# -ge 1 ] do
  for z; do
    ( cd -- "$(dirname "$z")" &&
      z=${z##*/} &&
      unzip -- "$z" &&
      rm -- "$z"
    )
  done
done

यदि आप shoptलाइन के साथ प्रतिस्थापित करते हैं तो स्क्रिप्ट भी zsh में काम करेगी setopt nullglob

यहाँ एक पोर्टेबल समकक्ष है। समाप्ति की स्थिति थोड़ी जटिल है क्योंकि findयह इंगित करने के लिए कि यह किसी भी फाइल को मिला है, अनायास वापस नहीं आती है। चेतावनी: ऊपर के रूप में।

while [ -n "$(find . -type f -name '*.zip' -exec sh -c '
    cd "${z%/*}" &&
    z=${z##*/} &&
    unzip -- "$z" 1>&2 &&
    rm -- "$z" &&
    echo 1
')" ]; do :; done

1

unzipऐसा नहीं करता है, क्योंकि UNIX तरीका एक काम करना है और यह अच्छी तरह से करना है, हर टूल में सभी पागल विशेष मामलों को संभालना नहीं है। इस प्रकार, आपको शेल का उपयोग करने की आवश्यकता है (जो "अच्छी तरह से चीजों को एक साथ बाँधने" का काम करता है)। यह इसे एक प्रोग्रामिंग प्रश्न बनाता है, और चूंकि StackOverflow पर सभी संभावित प्रोग्रामिंग प्रश्नों का उत्तर दिया गया है, आप यूनिक्स कमांड-लाइन से एक निर्देशिका और इसके उपनिर्देशिका में पुनरावर्ती अभिलेखागार कैसे प्राप्त करते हैं?


1
मैं निश्चित रूप से फोन नहीं होगा एक प्रोग्रामिंग सवाल, और "शेल पटकथा लेखन" "खोल का उपयोग करते हुए" विषय पर के रूप में पूछे जाने वाले प्रश्न में सूचीबद्ध है
माइकल Mrozek

मेरा तात्पर्य यह नहीं था कि यहाँ यह बिल्कुल विषय था, मैं सिर्फ यह बताना चाहता था कि स्टैकऑवरफ्लो में यह विषय क्यों है।
थॉमस थेमेल

1

यह पर्ल स्क्रिप्ट प्रत्येक .zip फ़ाइल को अपनी उपनिर्देशिका में निकालेगी। नेस्टेड ज़िप फ़ाइलों को संभालने के लिए स्क्रिप्ट को एक से अधिक बार चलाएं। यह निष्कर्षण के बाद .zip फ़ाइलों को नष्ट नहीं करता है, लेकिन आप एक अनलिंक () कॉल जोड़कर उस परिवर्तन को बना सकते हैं।

#!/usr/bin/perl -w

# This script unzips all .zip files it finds in the current directory
# and all subdirectories.  Contents are extracted into a subdirectory
# named after the zip file (eg. a.zip is extracted into a/).
# Run the script multiple times until all nested zip files are
# extracted.  This is public domain software.

use strict;
use Cwd;

sub process_zip {
    my $file = shift || die;
    (my $dir = $file) =~ s,/[^/]+$,,;
    (my $bare_file = $file);
    $bare_file =~ s,.*/,,;
    my $file_nopath = $bare_file;
    $bare_file =~ s,\.zip$,,;
    my $old_dir = getcwd();
    chdir($dir) or die "Could not chdir from '$old_dir' to '$dir': $!";
    if (-d $bare_file) {
        chdir($old_dir);
        # assume zip already extracted
        return;
    }
    mkdir($bare_file);
    chdir($bare_file);
    system("unzip '../$file_nopath'");
    chdir($old_dir);
}

my $cmd = "find . -name '*.zip'";
open(my $fh, "$cmd |") or die "Error running '$cmd': $!";
while(<$fh>) {
    chomp;
    process_zip($_);
}

1

सबसे आसान तरीका है, एटूल का उपयोग करना: http://www.nongnu.org/atool/ यह एक बहुत अच्छी स्क्रिप्ट है जो किसी भी संग्रह को निकालने के लिए ज़िप, अनज़िप, टार, रार आदि कार्यक्रमों का उपयोग करते हैं।

atool -x package_name.zipउन सभी को अनज़िप करने के लिए उपयोग करें या यदि आप इसे निर्देशिका में उपयोग करना चाहते हैं, तो कई ज़िप फ़ाइलों के साथ सरल forलूप का उपयोग करें :

for f in *; do atool -x $f; fi( cdइसका उपयोग करने से पहले आपको ज़िप फ़ाइलों के साथ वांछित निर्देशिका में आना होगा)।


atoolयहाँ बर्ताव से बहुत अलग नहीं है जैसा कि मैं कहूंगा कि यह ज़िप फ़ाइलों को फिर से नहीं निकालता है।
थॉमस थीमेल

@Thomas Themel: क्या आप सुनिश्चित हैं कि यह ज़िप फ़ाइलों को पुन: प्राप्त नहीं करता है? यह डिबेट फ़ाइलों से हटा सकता है। फिर भी मैं इसे

0

आप स्वचालित रूप से ज़िप फ़ाइलों के अंदर ज़िप फ़ाइलों को खोलना सावधान रहना चाहते हैं:

http://research.swtch.com/2010/03/zip-files-all-way-down.html

ज़िप फ़ाइल को आउटपुट के रूप में जनरेट करना संभव है, जो आउटपुट के रूप में एक ज़िप फ़ाइल का उत्पादन करता है, आदि आदि। यानी, आप एक ज़िप फ़ाइल बना सकते हैं जो कि "अनज़िप" प्रोग्राम की एक निश्चित मरहम है।

इसके अलावा, मुझे लगता है कि जिप फाइलें बनाने वाले लोगों को याद होगा जो "विस्फोट" करेंगे, यह एक बहुत छोटी ज़िप फ़ाइल है जो आउटपुट के बहु-गीगाबाइट को अनज़िप करेगी। यह संपीड़न की विधि का एक पहलू है।


0

शायद यह मदद करेगा (मेरे लिए काम किया):

function unzipAll(){

# find and count archives
archLst=`find . -type f -name "*.*ar"`
archLstSize=`echo $archLst| awk 'END{print NF}'`

# while archives exists do extract loop
while [ "$archLstSize" -gt 0 ]; do

# extract and remove all archives (found on single iteration)
for x in $archLst; do 
mv "${x}" "${x}_";
unzip "${x}_" -d "${x}" && rm "${x}_"; 
done; #EO for

# find and count archives
archLst=`find . -type f -name "*.*ar"`
archLstSize=`echo $archLst| awk 'END{print NF}'`

done #EO while

}

0

मुझे 2010 से जाइल्स जैसे समाधान की आवश्यकता थी, सिवाय इसके कि मुझे फ़ोल्डर संरचना को संरक्षित करने की आवश्यकता है, शीर्ष स्तर की निर्देशिका में सब कुछ अनज़िप न करें। यहाँ मेरी तीन लाइनों के साथ उसका जोड़ा गया / बदल गया:

#!/bin/bash
shopt -s globstar nullglob
while set -- **/*.zip; [ $# -ge 1 ]
do
    for z
    do
        ( cd -- "$(dirname "$z")" &&
            z=${z##*/} &&
            cp -- "$z" "$z".bak &&
            mkdir -- "$z"dir &&
            unzip -- "$z" -d "$z"dir &&
            rm -- "$z"
        )
    done
done

0

नेस्टेड ज़िप फ़ाइलों के लिए इस जावा आधारित उपयोगिता nzip चेकआउट करें । नेस्टेड ज़िप को एक्सट्रैक्ट करना और कंप्रेस करना निम्न कमांड्स का उपयोग करके आसानी से किया जा सकता है

java -jar nzip.jar -c लिस्ट -s readme.zip

जावा -जर nzip.jar -c अर्क -s "C: \ project \ readme.zip" -t readme

java -jar nzip.jar -c compress -s readme -t "C: \ project \ readme.zip"

पुनश्च। मैं लेखक हूं और किसी भी कीड़े को जल्दी ठीक करने में खुशी होगी।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.