वाइल्ड कार्ड चरित्र * कमांड जिप और आरएम के बीच इतना अलग क्यों है?


58

मैंने अपने लिए कुछ फ़ाइल संचालन करने के लिए एक स्क्रिप्ट रखी। मैं *एक प्रकार की सभी फ़ाइलों पर फ़ंक्शंस लागू करने के लिए वाइल्ड कार्ड ऑपरेटर का उपयोग कर रहा हूं , लेकिन एक चीज है जो मुझे नहीं मिलती है। मैं unzipइस तरह एक फ़ोल्डर में सभी फ़ाइलों को कर सकते हैं

unzip "*".zip

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

rm *.zip

यही है, यह उद्धरण चिह्नों को नहीं चाहता है। दूसरी ओर, अनज़िप, काम नहीं करता है अगर मैं सिर्फ इसे * देता हूं (मुझे एक चेतावनी देता है कि "फाइलें मेल नहीं खाती थीं")।

यह अलग क्यों है? मेरे लिए, यह ठीक उसी ऑपरेशन की तरह लगता है। या मैं गलत तरीके से वाइल्ड कार्ड का उपयोग कर रहा हूं?

यूनिक्स में वाइल्ड कार्ड के लिए परिचय वास्तव में इसमें नहीं जाते हैं, और मैं rmया zipडॉक्स में कुछ भी पता नहीं लगा सका ।

मैं एक मैक (Yosemite) पर टर्मिनल का उपयोग कर रहा हूं।


4
मुझे नहीं पता था unzipकि यह सामान्य for f in *.zip;do...doneशेल लूप के बिना हो सकता है । इस तरह के एक अजीब गैर-यूनिक्स जैसी कमांड लाइन यूआई।
पीटर कॉर्ड्स

@ मुझे लगता है कि आप स्थिति को गलत समझते हैं। unzipएक संग्रह की सामग्री पर ग्लोब लागू करता है; आप उन्हें वाइल्डकार्ड के साथ बैश नहीं कर सकते। (आपको f के लिए `` `की आवश्यकता होगी unzip -l archive.zip... किया`)
एलेक्सिस

@alexis: मुझे unzipग्लोब स्वीकार करने के बारे में एक ही ज़िप फ़ाइल के अंदर पता था । लेकिन यह अलग है; मैं वास्तव unzip '*.zip'में कई ज़िप फ़ाइलों के साथ एक निर्देशिका में कोशिश की है, और यह सभी ज़िप से सभी फ़ाइलों को निकालता है। जैसे मैंने कहा, सुपर-अजीब। tarइस तरह के ऑपरेशन का कोई तरीका नहीं है।
पीटर कॉर्ड्स

1
@Peter मैं देख रहा हूँ ... हाँ यह अजीब है, खासकर क्योंकि अनज़िप कई कमांडलाइन तर्कों को स्वीकार नहीं करेगा! स्पष्ट रूप से एक विंडोज-केवल कार्यान्वयन। मैंने कार्य के ओपी विवरण का गलत अर्थ निकाला।
एलेक्सिस

1
@alexis: PKZip विंडोज़ को प्री- डेट करता है । यह एक डॉस कमांड-लाइन प्रोग्राम है, जिसे 1989 में रिलीज़ किया गया था। यूनिक्स पोर्ट मूल रूप से एक ही cmdline- पार्सिंग कोड, AFAIK का उपयोग करता है।
पीटर कॉर्ड्स

जवाबों:


68

आपने स्थिति को बहुत अच्छे से समझाया है। पहेली का अंतिम टुकड़ा वह है जो unzipखुद वाइल्डकार्ड को संभाल सकता है:

http://www.info-zip.org/mans/unzip.html

ARGUMENTS

फ़ाइल [ज़िप]

...

वाइल्डकार्ड अभिव्यक्तियाँ आमतौर पर इस्तेमाल किए जाने वाले यूनिक्स गोले (sh, ksh, csh) में समर्थित हैं और इसमें शामिल हो सकते हैं:

* 0 या अधिक वर्णों के अनुक्रम से मेल खाता है

* वाइल्डकार्ड के हवाले से, आपने अपने शेल को इसे विस्तारित करने से रोक दिया, ताकि unzipवाइल्डकार्ड देखे और अपने तर्क के अनुसार इसे विस्तारित करने से संबंधित हो।

rm, इसके विपरीत, अपने दम पर वाइल्डकार्ड का समर्थन नहीं करता है , इसलिए वाइल्डकार्ड को उद्धृत करने का प्रयास करने के rmबजाय फ़ाइल नाम में एक शाब्दिक तारांकन देखने के लिए निर्देश देगा ।

unzip *.zipकाम नहीं करने का कारण यह है कि unzipवाक्यविन्यास बस कई ज़िप फ़ाइलों की अनुमति नहीं देता है; यदि कई पैरामीटर हैं, तो यह उम्मीद करता है कि संग्रह में 2 और बाद की फाइलें हों:

unzip [-Z] [-cflptTuvz [abjnoqsCDKLMUVWX $ /: ^]] फ़ाइल [.zip] [फ़ाइल (s) ...] [-x xfile (s)] [-d exdir]


6
धन्यवाद, यह समझ में आता है! अगर मैं सही ढंग से समझूं, तो एक मामले में मैं unzipअपनी भाषा बोल रहा हूं , दूसरे मामले में सामान्य यूनिक्स लिंगो?
पैट्रिक

6
सही बात। यह ध्यान रखना महत्वपूर्ण है कि आपका शेल क्या करता है बनाम एक कार्यक्रम क्या करता है।
जेफ स्कालर

7
pkzip की उत्पत्ति DOS पर हुई जो कि कार्यक्रमों में पारित वाइल्डकार्ड का विस्तार नहीं करती थी।
थोरबजोरन रेव एंडरसन

11
@ एक प्रोग्राम के साथ कई फ़ाइलों को संसाधित करने का यूनिक्स तरीका जो केवल एक बार में एक फ़ाइल के साथ काम कर सकता है वह है लूप का उपयोग करना। उदा for f in *.zip ; do unzip -v "$f" ; done। और इसका एक बड़ा कारण यह है कि शेल का फाइलनेम विस्तार आदि स्वयं ही क्यों नहीं किया जाता है, जो कि प्रत्येक व्यक्तिगत कार्यक्रम में नहीं होता है (जिसके परिणामस्वरूप वाइल्डकार्ड विस्तार के बहुत सारे स्वतंत्र रूप से लिखित कार्यान्वयन हो सकते हैं जो छोटे लेकिन कष्टप्रद तरीके से भिन्न होते हैं) ।
cas

25

उन दो आदेशों के बीच का अंतर उद्धृत *चरित्र है। यदि आप शेल में एक कमांड को कॉल करते हैं और *एक तर्क के लिए चरित्र का उपयोग करते हैं , तो शेल स्वयं तर्क का मूल्यांकन करेगा। इस उदाहरण को देखें:

$ ls
file1.zip  file2.zip  file3.zip  file4.txt

अब एक के साथ *:

$ ls *.zip
file1.zip  file2.zip  file3.zip

शेल वाइल्डकार्ड का मूल्यांकन करता है और निम्नानुसार एक कमांड बनाता है:

$ ls file1.zip  file2.zip  file3.zip

एक उद्धृत वाइल्डकार्ड के साथ, इसकी व्याख्या एक फ़ाइल के रूप में की गई है जिसका नाम (शाब्दिक रूप से) है *.zip:

$ ls "*".zip
ls: cannot access *.zip: No such file or directory

unzipउपयोगिता तर्क के रूप में कई ज़िप की गई फ़ाइलों के साथ नहीं कहा जा सकता। लेकिन, डेवलपर ने इसके लिए एक और तरीका चुना। मैनपेज से:

फ़ाइल [ज़िप]

[...] वाइल्डकार्ड अभिव्यक्तियाँ आमतौर पर इस्तेमाल किए जाने वाले यूनिक्स गोले (श, क्श, क्श) में समर्थित समान हैं [...] ( किसी भी वर्ण को उद्धृत करना सुनिश्चित करें जो अन्यथा ऑपरेटिंग सिस्टम द्वारा व्याख्या या संशोधित किया जा सकता है , विशेष रूप से के तहत यूनिक्स और वीएमएस।)


क्या आप जानते unzipहैं कि तर्क के रूप में कई ज़िपित फ़ाइलों के लिए अनुमति देने के बजाय लेखकों ने उस मार्ग को क्यों चुना?
डेविड एटलर

@DavidEtler मुझे भी नहीं पता है।
अराजकता

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

@DavidEtler को नहीं पता कि डेवलपर्स क्या सोच रहे थे, लेकिन तब सब कुछ बहुत धीमा और छोटा था । आप आमतौर पर एक समय में एक से अधिक ज़िप फ़ाइल के साथ काम नहीं कर रहे थे। आपके पास फ़्लॉपीज़ थी जो 90 या 250kB की थी और आप वास्तव में 10MB डिस्क ड्राइव पाकर खुश थे। चीजें संकुचित हो गईं क्योंकि उन्हें सिर्फ चौराहे के परिवहन के लिए ही होना था।
जो

7

अंतर पहले मामले में है जब शेल स्वयं ग्लोब का विस्तार करता है:

% cd /                                                       
% echo *
Applications Library Network System Users Volumes bin cores ...
% 

जबकि दूसरे मामले में आवेदन स्वयं उस शाब्दिक चरित्र के साथ कुछ करता है:

% cd /
% perl -E 'chdir "/tmp" or die; say for glob($ARGV[0])' "*"
com.apple.launchd.aj4FEhYqm5
...

यदि अयोग्य घोषित किया जाता है, तो शेल सबसे पहले ग्लोब को बाहर निकालता है, और कमांड को उस शेल ग्लोब के साथ चलाया जाएगा, जिसका विस्तार किया गया है।


2

शेल द्वारा संसाधित किए जाने के बाद एक कमांड तर्क प्राप्त करेगा।

पहले प्रसंस्करण पर, एक अनक्लोकेट *शेल द्वारा विस्तारित किया जाएगा (वर्तमान निर्देशिका में फ़ाइलों की सूची (pwd) जो पैटर्न से मेल खाती है):

echo *.zip

सभी .zipफाइलों को सूचीबद्ध करेगा । लेकिन नहींecho "*".zip" करेंगे ।

पहले प्रसंस्करण पर, एक उद्धृत "*"का विस्तार नहीं किया जाएगा, यह कमांड अनज़िप को एक पैरामीटर के रूप में दिया जाएगा (उद्धरण हटाने के बाद)। कमांड अनज़िप का एक पैरामीटर प्राप्त होगा *.zip:

$ echo unzip "*".zip
unzip *.zip

यह कमांड अनज़िप है जो *फाइलों की सूची में विस्तार करता है।


यह भी दिलचस्प है कि यह दो आदेश सटीक अंतिम कार्रवाई नहीं करेंगे, और जो *परिवर्तनों का विस्तार करता है:

unzip "*".zip                ### the command unzip expands `*.zip`.
unzip *.zip                  ### the shell expands `*.zip`.

पहला कमांड प्राप्त करता है *.zipजो सभी फाइलों को प्रोसेस करने के लिए फैलता है। दूसरी कमांड unzipको .zippwd में सभी फाइलों की एक सूची प्राप्त होगी , जिसे वह प्रोसेस नहीं करेगा, क्योंकि अनज़िप डेवलपर ने एक से अधिक zipफ़ाइल के विस्तार को अस्वीकार करने के लिए चुना है ।


0

जिप जिस तरह से कई तर्कों को संभालती है, उसके कारण उद्धरणों की आवश्यकता होती है:

rm: तर्क सूची में सभी फ़ाइलों को हटा दें

zip: फ़ाइल को पहले तर्क में अनज़िप करें। केवल शेष तर्कों में फ़ाइलें निकालें।

$ ls *.zip
file1.zip  file2.zip  file3.zip
$ unzip *.zip
Archive:  file1.zip
caution: filename not matched:  file2.zip
caution: filename not matched:  file3.zip

जैसा कि आप देख सकते हैं, यह file1.zip के अंदर file2.zip और file3.zip खोजने की कोशिश करता है

आपको एक साथ कई ज़िप फाइलें निकालने की अनुमति देने के लिए, ज़िप एक अलग परिणाम के साथ ग्लोब की व्याख्या करने का समर्थन करता है।

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