2012-11-05 15 views
5

के साथ निर्देशिका में प्रत्येक .jpg फ़ाइल पर स्क्रिप्ट चलाएं मेरे पास कुछ कामकाजी कोड है, यह बहुत आसान है - यह हर * .jpg फ़ाइल की प्रतिलिपि बनाता है, इसे * 1.jpg में बदलता है, कोई चिंता नहीं।बैश, उपनिर्देशिका

for i in *.jpg; do cp $i ${i%%.jpg}1.jpg; done 

मैं यह कैसे चला सकते हैं, इतना है कि यह है कि निर्देशिका

उदाहरण निर्देशिका संरचना के उप-निर्देशिकाओं के हर फ़ाइल एक निर्देशिका में हर फ़ाइल पर काम करता है,:

test/test1/test2/somefile.jpg 
    test/anotherfile.jpg 
    test/test1/file.jpg 
etc 
+2

'उस निर्देशिका की उपनिर्देशिका में प्रत्येक फ़ाइल' = पुनरावर्ती – nickhar

उत्तर

6

आदेश को एक निर्देशिका संरचना करने के लिए कुछ भी कर रिकर्सिवली find है:

find . -name "*.jpg" -exec bash -c 'file="{}"; cp "$file" "${file%%.jpg}1.jpg"' \; 

for i in $(find ...) के बजाय -exec का उपयोग करके फ़ाइल नामों को संभाल लेंगे जिनमें एक स्थान होता है। बेशक, अभी भी एक उद्धरण गोचा है; अगर फ़ाइल नाम में " है, तो file="{}"file="name containing "quote characters"" तक विस्तारित होगा, जो स्पष्ट रूप से टूटा हुआ है (filename containing quote बन जाएगा और यह characters कमांड निष्पादित करने का प्रयास करेगा)।

आप इस तरह के फ़ाइल नाम है, या आप, तो प्रत्येक फ़ाइल नाम रिक्त वर्ण (जो फ़ाइल नाम में अनुमति नहीं है) -print0 उपयोग करने के साथ अलग प्रिंट आउट हो सकता है, और अशक्त-सीमांकित परिणामों पर पाश के लिए while read -d $'\0' i का उपयोग करते हैं:

find . -name "*.jpg" -print0 | \ 
    (while read -d $'\0' i; do cp "$i" "${i%%.jpg}1.jpg"; done) 

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

find . -name "*.jpg" -print0 | \ 
    (while read -d $'\0' i; do echo cp "$i" "${i%%.jpg}1.jpg"; done) 

एक बार जब आप यह eyeballed है और परिणाम अच्छा लग रहा है, echo हटाएं और इसे वास्तविक के लिए चलाने के लिए इसे फिर से चलाएं।

+0

खोजें। -नाम "* .jpg" -exec bash -c 'फ़ाइल = "{}"; सीपी "$ फाइल" "$ {file %%। jpg} 1.jpg" '\; सही लिपि है, बहुत बहुत धन्यवाद – user1051532

2

आप बैश 4 है, तो आप पुनरावर्ती फ़ाइल नाम विस्तार (यानी रूप में अच्छी तरह उपनिर्देशिका में फ़ाइलों का मिलान) सक्षम करने के लिए उपयोग कर सकते हैं globstar

shopt -s globstar 
for i in **/*.jpg; do cp "$i" "${i%%.jpg}1.jpg"; done 

पी/एस: मैं वहाँ मामले में cp के लिए बहस के आसपास उद्धरण जोड़ा फाइलनाम या क्या नहीं में रिक्त स्थान हैं।

संबंधित मुद्दे