2012-05-09 12 views
163

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

उदाहरण के लिए, 1 फ़ाइल पर कमांड को चलाने के लिए:

$ cmd [option] [filename] > results.out 
+3

मैं प्रश्न में जोड़ने के लिए चाहते हैं। क्या यह xargs का उपयोग कर किया जा सकता है? उदाहरण के लिए, 'एलएस | xargs cmd [विकल्प] {फ़ाइल नाम स्वचालित रूप से xargs द्वारा डाले गए हैं} [अधिक तर्क]> results.out' –

+0

यह हो सकता है, लेकिन आप शायद ['ls'] का उपयोग नहीं करना चाहते हैं (http: //mywiki.wooledge। संगठन/पार्सिंग एलएस) 'xargs' ड्राइव करने के लिए। यदि 'cmd' सभी सक्षम रूप से लिखे गए हैं, तो शायद आप 'cmd ' कर सकते हैं। – tripleee

उत्तर

244

निम्नलिखित बैश कोड को आदेश जहां $ फ़ाइल में हर फ़ाइल/dir

for file in /dir/* 
do 
    cmd [option] "$file" >> results.out 
done 

उदाहरण का प्रतिनिधित्व करेंगी $ फ़ाइल पारित करेंगे

[email protected] ~/foo $ touch foo.txt bar.txt baz.txt 
[email protected] ~/foo $ for i in *.txt; do echo "hello $i"; done 
hello bar.txt 
hello baz.txt 
hello foo.txt 
+13

यदि'/dir/'में कोई फ़ाइल मौजूद नहीं है, तो लूप अभी भी '$' के मान के साथ '*' के मान के साथ चलता है, जो अवांछित हो सकता है। इससे बचने के लिए, लूप की अवधि के लिए nullglob सक्षम करें। लूप 'shopt -s nullglob' से पहले इस लाइन को जोड़ें और लूप' shopt -u nullglob #revert nullglob को इसके सामान्य डिफ़ॉल्ट स्थिति पर वापस करने के बाद इस पंक्ति को जोड़ें। –

+29

+1, और यह सिर्फ मुझे मेरा पूरा वॉलपेपर संग्रह खर्च किया। मेरे बाद हर कोई, डबलक्वॉट्स का उपयोग करें। "$ फ़ाइल" – Behrooz

+0

यदि आउटपुट फ़ाइल लूप के अंदर समान है, तो लूप 'done> results.out' के बाहर रीडायरेक्ट करना अधिक कुशल है (और संभवतः आप संलग्न करने के बजाय ओवरराइट कर सकते हैं, जैसा कि मैंने यहां माना है)। – tripleee

112

कैसे इस बारे में:

find /some/directory -maxdepth 1 -type f -exec cmd option {} \; > results.out 
  • -maxdepth 1 तर्क रिकर्सिवली किसी भी उपनिर्देशिका में उतरते से लगता है रोकता है। (यदि आप ऐसी नेस्टेड निर्देशिकाओं को संसाधित करना चाहते हैं, तो आप इसे छोड़ सकते हैं।)
  • -type -f निर्दिष्ट करता है कि केवल सादे फाइलों को संसाधित किया जाएगा।
  • -exec cmd option {}, यह बताता है फ़ाइल नाम के लिए {}
  • \; एवजी के साथ प्रत्येक फ़ाइल के लिए निर्दिष्ट option पाया साथ cmd चलाने के लिए कमांड के अंत को दर्शाता है।
  • अंत में, सभी अलग-अलग cmd फांसी से उत्पादन results.out

पर भेज दिया जाएगा हालांकि, अगर आप जिस क्रम में फ़ाइलों को संसाधित कर रहे हैं के बारे में परवाह है, तो आप एक पाश लेखन से बेहतर हो सकता है। मुझे लगता है कि find इनोड ऑर्डर में फ़ाइलों को संसाधित करता है (हालांकि मैं इसके बारे में गलत हो सकता हूं), जो नहीं हो सकता है।

+1

फाइलों को संसाधित करने का यह सही तरीका है। लूप का उपयोग करना कई कारणों से त्रुटि-प्रवण है। इसके अलावा अन्य स्टेटस जैसे 'stat' और' sort' का उपयोग करके सॉर्टिंग किया जा सकता है, जो निश्चित रूप से सॉर्टिंग मानदंडों पर निर्भर करता है। – tuxdna

+0

अगर मैं दो आदेशों को चलाने के लिए चाहता हूं तो मैं उन्हें '-exec' विकल्प के बाद कैसे लिंक करूं? क्या मुझे उन्हें सिंगल कोट्स या कुछ में लपेटना है? – frei

+0

'find' हमेशा सबसे अच्छा विकल्प होता है क्योंकि आप फ़ाइल नाम पैटर्न द्वारा विकल्प '-name' के साथ फ़िल्टर कर सकते हैं और आप इसे एक ही कमांड में कर सकते हैं। –

2

@Jim लुईस के दृष्टिकोण के आधार पर:

यहां find का उपयोग करके एक त्वरित समाधान है और उनकी संशोधन तिथि द्वारा फ़ाइलों को सॉर्ट करना भी है:

$ find directory/ -maxdepth 1 -type f -print0 | \ 
    xargs -r0 stat -c "%y %n" | \ 
    sort | cut -d' ' -f4- | \ 
    xargs -d "\n" -I{} cmd -op1 {} 

छँटाई देखें:

http://www.commandlinefu.com/commands/view/5720/find-files-and-list-them-sorted-by-modification-time

22

मैं कमांड लाइन से मेरी रास्पबेरी पाई पर इस कर रहा हूँ चलाकर:

for i in *;do omxplayer "$i";done 
1

मैं सभी .md फ़ाइलों की प्रतिलिपि करने के लिए आवश्यक एक निर्देशिका से दूसरे में, तो यहां मैंने जो किया है।

for i in **/*.md;do mkdir -p ../docs/"$i" && rm -r ../docs/"$i" && cp "$i" "../docs/$i" && echo "$i -> ../docs/$i"; done

कौन सा सुंदर पढ़ने के लिए कठिन है, इसलिए इसे तोड़ने के नीचे की सुविधा देता है।अपने पैटर्न

mkdir -p ../docs/"$i" में अपनी फाइलों के साथ निर्देशिका में

पहले सीडी,

प्रत्येक फ़ाइल के लिए for i in **/*.md; आपकी फ़ाइलों वाले फ़ोल्डर के बाहर एक डॉक्स फ़ोल्डर में है कि निर्देशिका हैं। जो उस फ़ाइल के समान नाम के साथ एक अतिरिक्त फ़ोल्डर बनाता है।

rm -r ../docs/"$i" कि mkdir -p

cp "$i" "../docs/$i" कॉपी वास्तविक फ़ाइल

echo "$i -> ../docs/$i" इको आप क्या किया

; done खुशी से लाइव

1

एक त्वरित परिणाम के रूप में बनाया जाता है अतिरिक्त फ़ोल्डर निकालना और गंदे तरीके से जो काम कभी-कभी किया जाता है वह है:

उदाहरण मौजूदा निर्देशिका में सभी फ़ाइलों में लाइनों की संख्या को खोजने के लिए के लिए, आप कर सकते हैं:

find . | xargs wc -l