यह डेविड उदास कर देता है ...
हर कोई अब तक (anubhava को छोड़ कर) गलत है।
शैल स्क्रिप्टिंग किसी भी अन्य प्रोग्रामिंग भाषा की तरह नहीं है क्योंकि कमांड वास्तव में निष्पादित होने से पहले लाइनों की व्याख्या में से अधिकतर शैल की शक्ति से आती है।
के कुछ सरल लेते हैं:
$ set -x
$ ls
+ ls
bar.txt foo.txt fubar.log
$ echo The text files are *.txt
echo The text files are *.txt
> echo The text files are bar.txt foo.txt
The text files are bar.txt foo.txt
$ set +x
$
set -x
आप देखना चाहते हैं कि खोल वास्तव में ग्लोब interpolates की अनुमति देता है और फिर से गुजरता है कि वापस इनपुट के रूप में आदेश करने के लिए। >
उस रेखा को इंगित करता है जिसे वास्तव में आदेश द्वारा निष्पादित किया जा रहा है।
आप देख सकते हैं कि echo
कमांड *
की व्याख्या नहीं कर रहा है। इसके बजाय, खोल *
पकड़ता है और इसे मिलान करने वाली फ़ाइलों के नाम से बदल देता है। फिर और केवल तभी echo
कमांड कमांड को निष्पादित करता है।
आप 40K प्लस फ़ाइलें है, और आप grep *
करते हैं, आप विस्तार कर रहे हैं कि उन 40,000 से अधिक फ़ाइलों के नाम के *
grep
से पहले भी निष्पादित करने के लिए एक मौका है, और कहा कि जहां त्रुटि संदेश /usr/bin है/grep: तर्क सूची बहुत लंबी से आ रही है।
$ find . -name "*.kaks" -type f -maxdepth 1 | xargs grep -f A01/genes.txt
find . -name "*.kaks" -type f -maxdepth 1
अपने *.kaks
फ़ाइलों के सभी मिल जाएगा, और -depth 1
केवल मौजूदा निर्देशिका में फ़ाइलों को शामिल करेगा:
सौभाग्य से, यूनिक्स इस दुविधा के चारों ओर एक रास्ता है। -type f
सुनिश्चित करता है कि आप केवल फाइलें चुनें, न कि निर्देशिका।
find
आदेश पाइप फ़ाइलों के नाम xargs
और xargs
में grep -f A01/genes.txt
आदेश करने के लिए फ़ाइल के नाम में संलग्न कर देगा। हालांकि, xargs
में आस्तीन है। यह जानता है कि कमांड लाइन बफर कितना समय है, और कमांड लाइन बफर भरने पर grep
निष्पादित करेगा, फिर फ़ाइल की दूसरी श्रृंखला grep
पर पास करें। इस तरह, grep
को तीन या दस बार निष्पादित किया जाता है (कमांड लाइन बफर के आकार के आधार पर), और हमारी सभी फाइलों का उपयोग किया जाता है।
दुर्भाग्यवश, xargs
फ़ाइल नामों के लिए एक विभाजक के रूप में व्हाइटस्पेस का उपयोग करता है। यदि आपकी फ़ाइलों में रिक्त स्थान या टैब हैं, तो आपको xargs
के साथ परेशानी होगी। सौभाग्य से, वहाँ एक और ठीक है:
$ find . -name "*.kaks" -type f -maxdepth 1 -print0 | xargs -0 grep -f A01/genes.txt
-print0
find
कारण नई पंक्तियों द्वारा अलग नहीं फ़ाइलों के नाम मुद्रित करने के लिए होगा, लेकिन NUL चरित्र द्वारा। -0
पैरामीटर xargs
xargs
बताता है कि फ़ाइल विभाजक सफेद जगह नहीं है, लेकिन एनयूएल चरित्र है। इस प्रकार, इस मुद्दे को हल करता है।
तुम भी ऐसा भी कर सकता है:
$ find . -name "*.kaks" -type f -maxdepth 1 -exec grep -f A01/genes.txt {} \;
यह प्रत्येक के लिए grep
और बदले xargs
क्या करता है की पाया हर फ़ाइल को निष्पादित करेंगे और केवल सभी फाइलों को यह कमांड लाइन पर सामान कर सकते हैं के लिए grep
चलाता है। इसका लाभ यह है कि यह पूरी तरह से खोल हस्तक्षेप से बचाता है। हालांकि, यह कम कुशल नहीं हो सकता है या नहीं भी हो सकता है।
प्रयोग करना दिलचस्प होगा और देखें कि कौन सा अधिक कुशल है। आप को देखने के लिए time
उपयोग कर सकते हैं:
$ time find . -name "*.kaks" -type f -maxdepth 1 -exec grep -f A01/genes.txt {} \;
यह आदेश पर अमल और उसके बाद आपको बता कितना समय ले लिया जाएगा। इसे -exec
और xargs
के साथ आज़माएं और देखें कि तेज़ क्या है। अपनी खोज के बारे में हमें जरूर बताएं।
मुझे लगता है कि आप – keyser