कई फाइलों पर कमांड चलाना


19

मुझे कई फ़ाइलों के साथ एक फ़ोल्डर मिला है (xyz1, xyz2, सभी तरह से xyz5025 तक) और मुझे उनमें से हर एक पर एक स्क्रिप्ट चलाने की ज़रूरत है, xyz1.faa, xyz2.faa और इतने पर आउटपुट मिल रहा है।

एकल फ़ाइल के लिए कमांड है:

./transeq xyz1 xyz1.faa -table 11

क्या स्वचालित रूप से ऐसा करने का कोई तरीका है? शायद एक कॉम्बो करने के लिए?

जवाबों:


32
for file in xyz*
do
  ./transeq "$file" "${file}.faa" -table 11
done

यह एक साधारण forलूप है जो xyzमौजूदा डायरेक्टरी में शुरू होने वाली हर फाइल पर ./transeqटाइप करेगा और पहले तर्क के रूप में फाइलनेम के साथ प्रोग्राम को कॉल करेगा , इसके बाद फाइलनेम ".faa" को दूसरे तर्क के रूप में, इसके बाद "-अवसाद 11" के रूप में। ।


4
या, एक-लाइनर के रूप में for file in xyz*; do ./transeq "$file" "${file}.faa" -table 11; done:। मैं हर समय इस तरह की चीज टाइप करता हूं। और अगर आप यह सत्यापित करना चाहते हैं कि फ़ाइल नाम, आदि आपके इच्छित तरीके का विस्तार कर रहे हैं, तो बस पहली बार के echoबाद एक अधिकार डालें do, और फिर अपने शेल इतिहास में वापस जाएं और इसे दूसरी बार हटाएं।
डेव ट्वीड

"$file".faaएक इंटरैक्टिव वन-लाइनर के हिस्से के रूप में टाइप करना थोड़ा आसान है, और सुरक्षित है क्योंकि .faaइसमें कोई भी शेल मेटाचैकर्स शामिल नहीं है जिसे उद्धृत करने की आवश्यकता है।
पीटर कॉर्डेस

2
एक नोट के रूप में, यदि आप एक आंशिक रन के साथ समाप्त होते हैं और लूप को फिर से शुरू करना चाहते हैं, तो xyz*ग्लोब .faa फ़ाइलों को भी उठाएगा। बैश के लिए, रन shopt -s extglob( संदर्भ ), फिर for file in xyz!(*.faa) ....fa फ़ाइलों को लूप के माध्यम से भेजे जाने से रोकने के लिए उपयोग करें।
जेफ स्कालर

24

यदि आप GNU समानांतर स्थापित करते हैं, तो आप इसे इस तरह से समानांतर में कर सकते हैं:

parallel ./transeq {} {}.faa -table 11 ::: xyz*

यदि आप प्रोग्राम सीपीयू इंटेंसिव हैं तो इसे काफी तेज करना चाहिए।


6

आप bashकमांड लाइन पर ऐसा कुछ कर सकते हैं :

printf '%s\n' {1..5025} | xargs -l -I {} -t ./transeq xyz{} xyz{}.faa -table 11

हम पूर्णांक 1 से 5025 तक उत्पन्न कर रहे हैं, एक / लाइन, फिर उन्हें एक-एक करके xargs खिलाते हैं, जो पूर्णांक को इनकैप्सुलेट करता है {}और फिर इसे एक उचित तरीके से / .transeq कमांड लाइन में ट्रांसप्लांट करता है।

यदि आपके पास ब्रेस-विस्तार की सुविधा नहीं होनी चाहिए, {n..m}तो आप seqउन संख्याओं को उत्पन्न करने के लिए उपयोगिता को लागू कर सकते हैं ।

या, आप हमेशा संख्यात्मक पीढ़ी का अनुकरण कर सकते हैं:

yes | sed -n =\;5025q | xargs ...

1
यह रास्ता जटिल है। for i in {1..5025}; do ./transeq "xyz$i" "xyz$i".faa -table 11; doneरास्ता सोचने के लिए और प्रकार है। यदि आप इसे निष्पादित करने से पहले कमांड प्रिंट करना चाहते हैं, तो उपयोग करें set -x
पीटर कॉर्डेस

हाँ, यह सही है, लेकिन ओपी ने जिस तरह से प्रश्न तैयार किया, वह मुझे ऐसा लगा कि केवल xyz1 .. xyz5025 नाम वाली फाइलें ही रूचि थीं। इसलिए मैंने सोचा कि अगर हम इसे xyz * के लिए उपयोग करते हैं तो हमें गैर-अनुरूपण फ़ाइलों को अस्वीकार करने का एक तरीका चाहिए ... इसलिए यह। आदर्श रूप से, यदि ओपी एक निर्देशिका में सभी फाइलों को संसाधित करना चाहता है, तो 1 से 5025 की चीज क्यों लाएं? बस इतना कहूंगा कि मैं चाहता हूं कि निर्धारित तरीके से संसाधित सभी फाइलें पर्याप्त हों।

1
मैंने जो लूप लिखा, उसे देखिए। यह का उपयोग करता है for i in {1..5025}को प्राप्त करने के बिल्कुल तुम्हारा के रूप में एक ही परिणाम। आप for ((i=1 ; i<=5025 ; i++)); do ./transeq "xyz$i" "xyz$i".faa -table 11; doneबैश में भी लिख सकते हैं , लेकिन मैं आमतौर पर {a..b}रेंज सिंटैक्स का उपयोग करता हूं क्योंकि यह टाइप करने के लिए तेज़ है।
पीटर कॉर्डेस

4

अपनी फ़ाइलों को निर्देशिकाओं के अंदर बिखरे होने पर उपयोगी, खोज का उपयोग करें

find -name "xyz*" -exec ./transeq {} {}.faa -table 11 \;

4

यह मानते हुए कि आपके पास एक से अधिक कोर हैं, और प्रत्येक आह्वान स्वतंत्र रूप से बाकी हिस्सों से चल सकता है, आप समानांतर रन के साथ काफी गति प्राप्त करेंगे।

ऐसा करने का एक अपेक्षाकृत सरल तरीका है - के -Pपैरामीटर के माध्यम से xargs- उदाहरण के लिए, यदि आपके पास 4 कोर हैं:

echo xyz{1..5025} | \
    xargs -n 1 -P 4 -I{} /path/to/transeq xyz{} xyz{}.faa -table 11

-n 1बताता xargsप्रत्येक मंगलाचरण के लिए सूची में से केवल एक तर्क लेने के लिए (डिफ़ॉल्ट रूप से यह बहुत से होकर गुजरेगा) , और -P 4यह बताता है एक ही समय में 4 प्रक्रियाओं अंडे देने के लिए - जब एक मरता, एक नया पैदा की है।

IMHO, आपको इस सरल मामले के लिए GNU समानांतर स्थापित करने की आवश्यकता नहीं है - xargsपर्याप्त है।


0

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

ls | xargs -L 1 -d '\n' your-desired-command

-L 1 एक बार में 1 आइटम पास करने का कारण बनता है

-d '\n'के मेकअप उत्पादन lsहै नई लाइन के आधार पर split'ed।

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