ज़िप फ़ाइल को "अनएक्सट्रेक्ट" कैसे करें?


52

मैंने एक नॉन-खाली फोल्डर में जिप फाइल निकाली। ज़िप फ़ाइल में बहुत सारी फाइलें और एक गहरी पदानुक्रम है, जो लक्ष्य निर्देशिका के मौजूदा पेड़ के साथ विलय कर दिया गया है। मैं उन फ़ाइलों और निर्देशिकाओं को कैसे हटा सकता हूं, जहां पहले से ही मौजूद फ़ाइलों और निर्देशिकाओं को नष्ट किए बिना बनाया गया था? बेशक, मेरे पास अभी भी जिप फाइल है जिसे मैंने मर्ज कर दिया है, इसलिए जानकारी है।


उम्म को स्वीकार करने के लिए धन्यवाद, लेकिन यह वास्तव में @ jjin का विचार था। मुझे इसके lqविकल्पों के बारे में पता नहीं था unzizp, मैंने सिर्फ उसके मुख्य उत्तर के आसपास कुछ क्लासिक * निक्स ट्रिक्स जोड़े।
टेराडॉन

यह ठीक है, मुझे वास्तव में इतना ध्यान नहीं है। मैंने वैसे भी व्हॉट्सएप-हैंडलिंग का अपना अलग संस्करण जोड़ा।
jjlin

@terdon हाँ ... मैंने jjlin के उत्तर को भी गलत ठहराया है, लेकिन मैं केवल एक उत्तर को स्वीकार कर सकता हूं।
1

भविष्य के संदर्भ के लिए, हमेशा किसी भी प्रारूप के किसी अपरिचित संग्रह के साथ निम्नलिखित में से एक करें: 1) इसे खाली निर्देशिका में निकालें या 2) इसे निकालने से पहले इसे पहले (अनज़िप-एल) सूचीबद्ध करें ताकि आप देख सकें कि क्या यह इस तरह से गंदा है। शीर्ष स्तर की निर्देशिका के बिना बनाए गए अभिलेख, जो सभी प्रकार से खराब हैं, खराब हैं। जब टार के साथ किया जाता है, तो उन्हें वास्तव में टार बम कहा जाता है, इसलिए मुझे लगता है कि इसे जिप बम कहा जा सकता है।
जो

@ जोए इसके उपयोग हैं। LaTeX पैकेज, उदाहरण के लिए, एक foo.tds.zipफॉर्म में आ सकते हैं । ये ज़िप एक TEXMF पेड़ में विलीन हो जाते हैं, जो बहुत सुविधाजनक है। लेकिन अगर आप कभी भी इस तरह के पैकेज को हटाना चाहते हैं तो आपको मेरे द्वारा बताई गई समस्या का सामना करना पड़ेगा।
mafp

जवाबों:


28

jjlin का जवाब जाने का रास्ता है। मैं सिर्फ निर्देशिका के लिए कुछ विकल्प जोड़ना चाहता हूं:

  • सभी निकाले गए फ़ाइलों को हटाएँ , कोई निर्देशिका नहीं :

    unzip -lqq file.zip | gawk -F"  " '{print $NF;}' |
      while IFS= read -r n; do rm "$n"; done
  • केवल निकाली गई फ़ाइलें और खाली निर्देशिका हटाएं

    unzip -lqq file.zip | gawk -F"  " '{print $NF;}' |
      while IFS= read -r n; do rm "$n"; done; rmdir *

    कोई विकल्प नहीं होने पर, rmdirकेवल खाली निर्देशिकाओं को हटाता है, यह फ़ाइलों और गैर-खाली फ़ोल्डरों को अकेला छोड़ देगा ताकि आप इसे सुरक्षित रूप से चला सकें *

  • निकाले गए सभी चीज़ों को हटाएं , लेकिन प्रत्येक विलोपन से पहले पुष्टि के लिए संकेत दें:

    unzip -lqq file.zip | gawk -F"  " '{print $NF;}' |
      while IFS= read -r n; do rm -ri "$n"; done; rmdir *

    -iध्वज का कारण होगा rmहर हटाने से पहले संकेत करने के लिए, आप हाँ या नहीं चुन सकते हैं

  • निकाली गई सभी चीज़ों को हटा दें , निर्देशिकाओं में शामिल हैं:

    unzip -lqq file.zip | gawk -F"  " '{print $NF;}' |
      while IFS= read -r n; do rm -rf "$n"; done

खाली निर्देशिकाओं को हटाना आसानी से होता है find: find * -depth -type d -exec rmdir {} +और सभी Directory not emptyसंदेशों को अनदेखा करना । इसे विकल्प के find * -type d -deleteरूप में छोटा करना कानूनी हो सकता है, लेकिन -deleteविकल्प पर -depthमैंने सत्यापित नहीं किया है कि -deleteयह गैर-रिक्त निर्देशिका को नष्ट नहीं करेगा।
एड्रियन प्रोक

@ एड्रियनप्रोनक यह नहीं करता:find: cannot delete './foo': Directory not empty
टेराडो

28

आप unzip -lqq <filename.zip>ज़िप फ़ाइल की सामग्री को सूचीबद्ध करने के लिए उपयोग कर सकते हैं ; इसमें कुछ बाहरी जानकारी शामिल होगी, जिन्हें आपको फ़िल्टर करना होगा, हालाँकि। यहाँ एक कमांड है जो मेरे लिए काम करती है:

unzip -lqq file.zip | awk '{print $4;}' | xargs rm -rf

awkआदेश अर्क सिर्फ फाइलों और निर्देशिकाओं के नाम। फिर xargsसब कुछ डिलीट करने के लिए रिजल्ट पास हो जाता है । मैं यह सुनिश्चित करने के लिए आदेश के ड्राई-रन (यानी xargs rm -rfभाग को छोड़ कर ) करने का सुझाव देता हूं ताकि परिणाम सही हो।

उपरोक्त कमांड में व्हाट्सएप वाले रास्तों से निपटने के मुद्दे होंगे। इस (अधिक जटिल) संस्करण को ठीक करना चाहिए:

unzip -lqq file.zip | awk '{$1=$2=$3=""; sub(/ */, "", $0); printf "%s%s", $0, "\0"}' | xargs -0 rm -rf

यह मेरे दिमाग में पहले से ही काफी करीब है, लेकिन unzip -lqqजिप में निहित निर्देशिकाओं को भी सूचीबद्ध करता है। अभी के लिए, मैं सभी निर्देशिकाओं को अकेले जाने दूंगा। किसी वृक्ष की सभी खाली निर्देशिकाओं को कैसे हटाया जाए, यह एक अनुवर्ती प्रश्न हो सकता है।
mafp

@mafp यह निर्देशिकाओं के बारे में एक अच्छा बिंदु है। आप grep -v '/$'निर्देशिकाओं को हटाने के लिए पाइपलाइन में जोड़ सकते हैं (जिसमें सभी एक अनुगामी स्लैश, AFAICT है)।
jjlin

@terdon वास्तव में मुझे लगता है कि समस्या शुरू होती है awk, क्योंकि सिर्फ $ 4 का मुद्रण पूर्ण पथ को प्रिंट नहीं करेगा।
jjlin

मुझे नहीं लगता कि आपको -rrm के विकल्प का उपयोग करना चाहिए : जो परेशानी के लिए पूछ रहा है, खासकर जब -fविकल्प के साथ संयुक्त । मैं -fइस परिदृश्य में विकल्प का उपयोग नहीं करूंगा ।
एड्रियन प्रोक

1
@jjlin: grep -v '/$'केवल ज़िप फ़ाइल में निर्देशिका प्रविष्टियों को छोड़ना होगा। वे अभी भी ऐसी प्रविष्टियाँ शामिल करेंगे जो ज़िप फ़ाइल में सादे फ़ाइलें थीं, लेकिन लक्ष्य फ़ोल्डर में पहले से मौजूद निर्देशिका थीं। इस कारण से, इसे छोड़ना बुद्धिमान होगा-r
एड्रियन प्रैंक

11

स्विच के साथ -Z1, unzip प्रति पंक्ति एक फ़ाइल (और कुछ नहीं) को सूचीबद्ध करेगा।

इस तरह, आप उपयोग कर सकते हैं

unzip -Z1 | xargs -I {} rm '{}'

ज़िप फ़ाइल से निकाली गई सभी फ़ाइलों को हटाने के लिए।

आदेश

unzip -Z1 | xargs -I {} rm -rf '{}'

निर्देशिकाओं को भी हटा देगा, लेकिन आपको सावधान रहना होगा। यदि ज़िप फ़ाइल को निकालने से पहले ही निर्देशिका मौजूद थी, तो उन निर्देशिकाओं में मौजूद सभी मौजूदा फ़ाइलों को भी हटा दिया जाएगा।


यदि आप वैसे भी ज़िप फ़ाइल को फिर से निकालने जा रहे हैं, तो एक और दृष्टिकोण है जो अजीब फ़ाइल नामों से निपटने की गारंटी है।

पहले ज़िप फ़ाइल को निकालें, जहाँ आप मूल रूप से इसे निकालने के लिए बने थे:

unzip file.zip -d elsewhere

अब, उस निर्देशिका में बदलें जहां आपने गलती से फाइलें निकाली हैं और निम्नलिखित कमांड निष्पादित करें:

find elsewhere -type f -printf "%P\0" | xargs -0 -I {} rm '{}'
  • -type f केवल फ़ाइलें (कोई निर्देशिका नहीं) पाता है।

  • %P\0सापेक्ष पथ (बिना elsewhere/), एक अशक्त चरित्र के बाद है।

  • -0शून्य वर्णों द्वारा xargs की अलग-अलग रेखाएँ बनाता है। यह अधिक विश्वसनीय है, क्योंकि - सिद्धांत रूप में - फ़ाइल नामों में न्यूलाइन वर्ण हो सकते हैं।


बचे हुए निर्देशिकाओं से निपटने के लिए, आप कमांड निष्पादित कर सकते हैं:

find -type d -exec rmdir -p {} \; 2> /dev/null
  • -type d केवल निर्देशिका पाता है।

  • -exec rmdir -p {} \;rmdir -p {}पाया गया है कि हर निर्देशिका के लिए निष्पादित करता है।

    {}निर्देशिका है कि पाया गया है, और -pस्विच rmdir बनाता है अपने खाली मूल निर्देशिका के रूप में अच्छी तरह से हटा दें।

  • 2> /dev/null उन त्रुटि संदेशों को दबा देता है जो गैर-रिक्त या पहले हटाए गए निर्देशिकाओं को हटाने की कोशिश से उत्पन्न होंगे।


संबंधित आदमी पृष्ठ:


मुझे पढ़ने के लिए zipinfoपेज बनाने के लिए +1 ।
टेराडो

खैर, जी, कि यह थोड़ा आसान बनाता है। :)
जजलिन

2

यहाँ एक और भी आसान और सुरक्षित (मुझे लगता है) समाधान है

zip -m getmeoutofhere.zip `unzip -lqq myoriginalzipfile.zip`
rm getmeoutofhere.zip

यह क्या कर रहा है: बैकपॉटेड अनज़िप कमांड आपकी मूल फ़ाइल में मौजूद सूची का उत्पादन करेगा।

zip -m फिर उस सूची को जोड़ने के लिए उपयोग करेगा कि प्रत्येक को getmeoutofhere.zip जोड़ें और इसे मूल निर्देशिका से हटा दें (इसलिए सैद्धांतिक रूप से यह myoriginalfile.zip के लिए संकेतक होना चाहिए।

नकारात्मक पक्ष यह है कि unzip -lqq कुछ अतिरिक्त पाठ, दिनांक, समय, फ़ाइलें आदि का उत्पादन करेगा, इनसे जिप-एम को त्रुटि संदेश उत्पन्न होगा लेकिन इसका कोई प्रभाव नहीं होना चाहिए (जब तक कि आपके पास एक फ़ाइल का असंभावित मामला न हो नाम)।

कृपया ध्यान दें कि यह उन सभी निर्देशिकाओं को नहीं हटाएगा जो मूल अनज़िप के दौरान बनाई गई थीं।


दिलचस्प दृष्टिकोण, आगे का पता लगाएगा।
mafp

1

यदि आपने फ़ाइलों को ऐसे निकाला है कि संग्रह में संशोधन टाइमस्टैम्प को निकाली गई प्रतियों में संरक्षित नहीं किया गया है (बल्कि निकाली गई फ़ाइलों का अपना सामान्य संशोधन समय है) तो इस पर हमला करने का सही तरीका संशोधन समय है। सभी निकाले गए फ़ाइलों में उस निर्देशिका में सबसे हाल ही में संशोधित मौजूदा फ़ाइल की तुलना में एक नया संशोधन टाइमस्टैम्प है।

यहाँ एक साधारण स्थिति है।

मान लीजिए कि वर्तमान निर्देशिका में कोई भी मौजूदा फ़ाइल कम से कम 24 घंटे तक नहीं छपी थी। कुछ भी जो पिछले 24 घंटों में संशोधित किया गया था, इसलिए जिप्फ़ाइल से रद्दी है।

$ find . -mtime -1 -print0 | xargs -0 rm

यह कुछ निर्देशिकाओं को भी ढूंढेगा, लेकिन rmउन्हें अकेला छोड़ देगा। उन्हें एक दूसरे पास से निपटाया जा सकता है:

$ find . -mtime 1 -type d -print 0 | xargs -0 rmdir

हाल ही में संशोधित किए गए किसी भी निर्देशिका को ज़िप द्वारा संशोधित किया गया था। यदि rmdirसफलतापूर्वक उन्हें हटा दिया जाता है, तो इसका मतलब है कि वे खाली हैं। खाली निर्देशिकाओं को जो ज़िप द्वारा छुआ गया था, संभवतः इसके द्वारा बनाई गई थीं: अर्थात संग्रह से। हम 100% निश्चित नहीं हो सकते। यह संभव है कि अनज़िप नौकरी ने कुछ फ़ाइलों को एक मौजूदा निर्देशिका में डाल दिया जो कि खाली थी।

यदि find24 घंटे की ग्रैन्युलैरिटी नौकरी के लिए पर्याप्त नहीं है, क्योंकि पेड़ की फाइलों को हाल ही में संशोधित किया गया था, तो मैं अगले कुछ सरल पर विचार करूंगा: मान लीजिए कि अनज़िप नौकरी ने मौजूदा उपनिर्देशिकाओं में कुछ भी नहीं डाला। यह कहना है, जो कुछ भी अनज़िप किया गया था वह या तो शीर्ष स्तर पर एक फ़ाइल है, या एक नया उपनिर्देशिका जो पहले नहीं था, इसलिए इसमें ज़िप से सामग्री के अलावा कुछ भी नहीं है। फिर:

# list directory in descending order of modification time
$ ls -1t > filelist  # descending order of modification time

अब हम filelistएक पाठ संपादक में खोलते हैं , और सूची में पहली प्रविष्टि निर्धारित करते हैं जो ज़िप से नहीं आई थी। हम उस प्रविष्टि और उसके बाद की सभी चीजों को हटा देते हैं। क्या अवशेष फाइलें और निर्देशिकाएं हैं जो ज़िप से आई हैं। सबसे पहले हम नामों में रिक्त स्थान जैसे मुद्दों के लिए नेत्रहीन निरीक्षण करते हैं, और उद्धरणों की घटनाओं से बचते हैं, जिन्हें बचने की आवश्यकता होती है। यदि आवश्यक हो तो हम सब कुछ के आसपास उद्धरण जोड़ सकते हैं: निम्नलिखित मानता है कि आप विम का उपयोग करते हैं:

:%s/.*/"&"/

फिर इसे एक बड़ी लाइन में शामिल करें:

:%j

अब rm -rfइसके सामने डालें :

Irm - rf<ESC>

एक शेल कमांड के रूप में कर्सर के नीचे लाइन को चलाएं:

!!sh<Enter>

निश्चित रूप से, मैं इस कार्य के चरणों को स्वचालित नहीं करूंगा, जो पहले से ही मौजूद फ़ाइलों को मिटाने या फ़ाइल नाम के मुद्दों के कारण खराब होने के जोखिम के कारण है।

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

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