BASH

2010-10-19 12 views
12

में रिक्त स्थान के साथ फ़ाइल नाम मैं स्क्रिप्ट लिखने की कोशिश कर रहा हूं जो बड़ी तस्वीरों को एचडी वॉलपेपर में फसल और आकार बदल देगा।BASH

#! /bin/bash 


for i in `ls *.jpg` 
do 
    width=`identify -format '%w' $i` 
    height=`identify -format '%h' $i` 

    if [ `echo "$width/$height > 16/9" | bc -l` ] 
    then 
     exec `convert $i -resize 1920 -gravity Center -crop '1920x1080+0+0' +repage temp` 
    else 
     exec `convert $i -resize x1080 -gravity Center -crop 1920x1080+0+0 +repage temp` 
    fi 

    rm $i 
    mv temp $i 
done 

लेकिन ऐसा लगता है कि स्क्रिप्ट में फ़ाइल नामों के साथ समस्याएं हैं (जैसे टम्बल वीड.जेपीजी)। मैं इसे कैसे ठीक करूं?

+2

उत्तर पहले से ही नीचे दिया गया है, लेकिन मैं यह जोड़ना चाहूंगा कि शेल स्क्रिप्टिंग फ़ाइल नामों में रिक्त स्थान को संभालने के लिए वास्तव में खराब है क्योंकि कई सूचियां स्थान-सीमित हैं - विशेष रूप से कमांड तर्क। उदाहरण के लिए एसपीपी के माध्यम से अंतरिक्ष के साथ एक फ़ाइल की प्रतिलिपि बनाने का प्रयास करें! मैन्युअल भागने के बिना यह लगभग असंभव है। – Timmmm

+2

आपको पूरी तरह से 'http: // mywiki.wooledge.org/BashPitfalls' पढ़ना चाहिए :-) यह आपके बैश कौशल – Benoit

उत्तर

20

सबसे पहले, आपको ls की आवश्यकता नहीं है। बैकटिक्स में ls का उपयोग करके, आप निस्संदेह एक स्ट्रिंग को एक सूची में स्ट्रिंग बनाते हैं, जो व्हाइटस्पेस द्वारा विभाजित होता है। इसके बजाय, बाश को सूची उत्पन्न करें और इस तरह के quirks के बिना इसे अलग करें:

इसके अलावा, आपको सभी $i उद्धरणों में उपयोगों को संलग्न करने की आवश्यकता है, ताकि इसे पूरी तरह से बैश विकल्प बनाया जा सके, न कि स्ट्रिंग अलग शब्दों के लिए विभाजित हो।

for i in *.jpg ; do 
    echo "$i"; 
done 
+0

फ़ाइल पथ में सफेद स्थान होने पर यह काम नहीं करता है। लाइन 2 पर आदेश (यह मामला 'echo') रिक्त स्थान को तर्क delimiters के रूप में व्याख्या करता है। – Diederik

+1

@Diederik, एचएम, यह मेरे खोल में सफेद जगहों के साथ काम करता है। Quites में '$ i' संलग्न करना चाल करता है। –

+0

आप सही मानते हैं, अगर सभी फाइलें एक ही निर्देशिका में हैं तो यह रिक्त स्थान के साथ भी काम करेगी। मेरी स्क्रिप्ट रिक्त स्थान के साथ विफल रही जब मैंने लूप के साथ 'ढूंढ' का उपयोग किया। फ़ोल्डर नाम में स्थान मेरी स्क्रिप्ट को बंद कर दिया। – Diederik

0

फ़ाइल नामों के चारों ओर डबल कोट्स का उपयोग करें। इस तरह:

width=`identify -format '%w' "$i"` 

कृपया "$i" के आसपास डबल कोट्स नोट करें।

4

मैं इस तरह के लिए लाइन लिखने के लिए सिफारिश करेंगे:

for i in *.jpg 

और $i डबल उद्धरण में संपुटित: "$i"


आप

`ls *.jpg` 

शैली पर जोर देते हैं, (यदि आप उदाहरण के लिए एक अधिक जटिल आदेश से अपनी फ़ाइल-नाम प्राप्त) यदि आप को सेट कर सकें IFS\n रहे हैं:

IFS='\n' 

इन दो निष्पादन की तुलना करें:

$ for f in `ls *`; do echo $f; done 
hello 
world 
test 

$ IFS='\n'; for f in `ls *`; do echo $f; done 
hello world 
test 
14

रिक्त स्थान के साथ समस्या को रोकने के लिए पढ़ें। यह इस तरह पाश लिखने के लिए एक सा अप्राकृतिक लग रहा है, लेकिन यह बेहतर काम करता है:

find . -type f -iname "*.jpg" | while read i 
do 
    # your original code inside the loop using "$i" instead of $i 
done 

-iname साथ आप भी .JPG की तरह अलग अलग आवरण के साथ एक विस्तार हो सकता है jpg फ़ाइलों मिलता है। "मैं" में "मैं" का मतलब आवरण को अनदेखा करता है।

+0

में काफी सुधार करेगा जैसा कि यह है, यह शाब्दिक बैकस्लाश, शाब्दिक न्यूलाइन के साथ नाम और नामों के साथ नामों में विफल रहता है सफेद जगह में समाप्त होता है। –

+0

इसे ठीक करने के लिए, 'ढूंढने' के लिए '-print0' जोड़ें, और खोल समाप्त करें' जबकि IFS = read -r -d '' i'; '-r' बैकस्लाश को ठीक करता है, '-d' '' और' -print0' शाब्दिक न्यूलाइन को ठीक करता है, और 'IFS =' व्हाइटस्पेस में समाप्त होने वाले नामों के लिए समर्थन को हल करता है। –

0
#! /bin/bash 
mkfifo ./lsOutput 
ls -1 *.jpg > ./lsOutput 
    while read line 
    do 

    width=`identify -format '%w' "$line"` 
    height=`identify -format '%h' "$line"` 

    if [ `echo "$width/$height > 16/9" | bc -l` ] 
    then 
     exec `convert "$line" -resize 1920 -gravity Center -crop '1920x1080+0+0' +repage temp` 
    else 
     exec `convert "$line" -resize x1080 -gravity Center -crop 1920x1080+0+0 +repage temp` 
    fi 

    rm "$line" 
    mv temp "$line" 
done<./lsOutput 
1

बैश में, उपयोग स्ट्रिंग प्रतिस्थापन खोजने के

$ {स्ट्रिंग //-स्ट्रिंग/प्रतिस्थापन}

Replace all matches of $substring with $replacement. 

साथ:

यहाँ स्क्रिप्ट है कि दोनों विचारों को दर्शाता है है इसलिए यह काम करता है:

खोजें। -type f -name '*।जेपीजी '| जबकि मैं पढ़ा; करो/bin/mv -f "$ i" $ {i ///_}; किया गया