अनज़िप में टार के "-स्ट्रिप-कंपोनेंट्स = 1" के बराबर?


48

मेरे पास एक स्क्रिप्ट है जो एक टारगेट -फाइल को एक निर्दिष्ट उपनिर्देशिका mysubfolder में निकालती है :

mkdir mysubfolder; tar --extract --file=sourcefile.tar.gz --strip-components=1 --directory=mysubfolder;

क्या ज़िप-फ़ाइल के साथ ऐसा करने का कोई समान तरीका है?


2
बस bsdtar का उपयोग करें
drizzt

जवाबों:


26

जैसा कि माथियास ने कहा, unzipइस तरह का कोई विकल्प नहीं है, लेकिन एक-लाइनर बैश स्क्रिप्ट काम कर सकती है।

समस्या यह है: सबसे अच्छा तरीका आपके आर्काइव लेआउट पर निर्भर करता है। एक समाधान जो एक शीर्ष स्तर के डीआईआर को मानता है, अगर सामग्री सीधे आर्क रूट में होती है (विचार करें /a/foo /b/foo /fooऔर स्ट्रिपिंग की अराजकता के बारे में ) /aऔर /b

और वही असफलता होती है tar --strip-component। कोई एक आकार-फिट-सभी समाधान नहीं है।

तो, जड़ dir पट्टी, यह मानते हुए वहाँ है एक (और केवल एक):

unzip -d "$dest" "$zip" && f=("$dest"/*) && mv "$dest"/*/* "$dest" && rmdir "${f[@]}"

बस यह सुनिश्चित करें कि दूसरे स्तर की फाइलें / dirs में शीर्ष-स्तरीय माता-पिता (उदाहरण के लिए ) का समान नाम नहीं है /foo/foo। लेकिन /foo/bar/fooऔर /foo/bar/barठीक हैं। यदि वे करते हैं, या आप सुरक्षित रहना चाहते हैं, तो आप निष्कर्षण के लिए एक अस्थायी डीआईआर का उपयोग कर सकते हैं:

temp=$(mktemp -d) && unzip -d "$temp" "$zip" && mkdir -p "$dest" &&
mv "$temp"/*/* "$dest" && rmdir "$temp"/* "$temp"

यदि आप बैश का उपयोग कर रहे हैं, तो आप परीक्षण कर सकते हैं कि शीर्ष स्तर एकल डायर है या उपयोग नहीं कर रहा है:

f=("$temp"/*); (( ${#f[@]} == 1 )) && [[ -d "${f[0]}" ]] && echo "Single dir!"

बैश की बात करते हुए, आपको dotglobछिपी हुई फ़ाइलों को शामिल करने के लिए चालू करना चाहिए , और आप एक ही, आसान कार्य में सब कुछ लपेट सकते हैं:

unzip-strip() (
    local zip=$1
    local dest=${2:-.}
    local temp=$(mktemp -d) && unzip -d "$temp" "$zip" && mkdir -p "$dest" &&
    shopt -s dotglob && local f=("$temp"/*) &&
    if (( ${#f[@]} == 1 )) && [[ -d "${f[0]}" ]] ; then
        mv "$temp"/*/* "$dest"
    else
        mv "$temp"/* "$dest"
    fi && rmdir "$temp"/* "$temp"
)

अब इसे अपने ~/.bashrcया ~/.profileआप के बारे में चिंता करने की ज़रूरत नहीं है। बस के रूप में उपयोग करें:

unzip-strip sourcefile.zip mysubfolder

( mysubfolderयदि यह मौजूद नहीं है तो यह आपके लिए स्वतः ही सूचना देगा )


यह एक मौजूदा निर्देशिका संरचना में नहीं खोलना होगा जैसा कि मुझे उम्मीद थी (मैंने mysubfolder के स्थान पर उपयोग करने का प्रयास किया है)। मैंने सिर्फ अनजिपिंग (unzip zip-with-top-dir.zip) को समाप्त किया और फिर कॉपी करना (cp -rv निकाले-टॉप-ज़िप-डायर / *।)।
कैटगोफायर

4

मुझे मैनुअल पृष्ठोंunzip में ऐसा कोई विकल्प नहीं मिला , इसलिए मुझे डर है कि यह असंभव है। :(

हालाँकि, (स्थिति के आधार पर) आप इसके आसपास काम कर सकते थे। उदाहरण के लिए, यदि आप सुनिश्चित हैं कि ज़िप फ़ाइल में एकमात्र शीर्ष-स्तरीय निर्देशिका का नाम foo-संस्करण संख्या में दिया गया है, तो आप कुछ ऐसा कर सकते हैं:

cd /tmp
unzip /path/to/file.zip
cd foo-*
cp -r . /path/to/destination/folder

अच्छा तरीका है, लेकिन थोड़ा अधूरा है: आपके पास अभी भी पूरी तरह से निकाली गई सामग्री के साथ फू * डायर होगा।
MestreLion

हां, मैं इस rm -rf foo-*उद्देश्य से नहीं जोड़ा कि यह संभावित रूप से खतरनाक है। क्या होगा अगर पहले से ही एक फ़ोल्डर नाम था foo-bar? ध्यान दें कि निष्कर्षण /tmpफ़ोल्डर के भीतर किया जा रहा है , जो हर अब और फिर स्वचालित रूप से खाली हो जाता है।
मथियास बिएनेंस

इसलिए मैंने ऑपरेशन का उपयोग करके जंजीर का उपयोग किया &&: एक दिया गया कदम केवल तभी होता है जब पिछला चरण सफल होता है, इसलिए अंतिम एक ( rm) केवल तभी चलता है जब सभी चरण बिना किसी त्रुटि के पूरा हो जाते हैं।
मेस्टेलियन

2
यही कारण है कि किसी को कभी भी /tmp/some-hardcoded-folder-nameएक अस्थायी फ़ोल्डर के रूप में उपयोगकर्ता नहीं करना चाहिए , बल्कि इसके mktempलिए उपयोग करना चाहिए : यह गारंटी देता है कि ऐसा कोई मौजूदा फ़ोल्डर नहीं होगा। नीचे मेरे जवाब की जाँच करें।
मेस्ट्रेलियन

1

आप -jरद्दी रास्तों का उपयोग कर सकते हैं (निर्देशिका नहीं बनाते हैं)। यह केवल कुछ सामान्य एकल-स्तरीय अभिलेखागार के लिए अनुशंसित है। मल्टी लेवल डायरेक्टरी स्ट्रक्चर्स वाले आर्काइव्स को चपटा किया जाएगा - इससे फाइल निकालने के लिए नाम क्लैश भी हो सकते हैं।

अनज़िप के मैन पेज से:

   -j     junk  paths.   The  archive's directory structure is not recreated; all files are deposited in the
          extraction directory (by default, the current one).
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.