2011-08-25 10 views
14

मैं एक फ़ाइल के नाम का उपयोग कर/tmp/में एक नया फ़ोल्डर बनाने के लिए एक बैश स्क्रिप्ट पर काम कर रहा हूं, और तब फ़ाइल को उस फ़ोल्डर के अंदर कॉपी करें।बेसनाम एक बैश स्क्रिप्ट में रिक्त स्थान के साथ?

#!/bin/bash 

MYBASENAME="`basename $1`" 
mkdir "/tmp/$MYBASENAME" 

for ARG in "[email protected]" 
    do 
     mv "$ARG" "/tmp/$MYBASENAME" 

done 

व्यवहार:

जब मैं mymove "/home/me/downloads/my new file.zip" में टाइप यह इस से पता चलता:

mkdir /tmp/my 
new 
file.zip 
mv: rename /home/me/downloads/my new file.zip to /tmp/my\nnew\nfile.zip: 

मैं सब कुछ के आसपास उद्धरण के बहुत सारे है, तो मुझे समझ नहीं आता क्यों इस अपेक्षा के अनुरूप काम नहीं कर रहा ।

इसके अलावा, मेरे पास कई फाइलें होने पर फॉर्म लूप है। मैं चाहता हूं कि उन सभी को पहले तर्क के बेसनाम पर आधारित एक ही फ़ोल्डर में कॉपी किया जाए।

उत्तर

12

इस मामले में जहां असाइनमेंट एक कमांड प्रतिस्थापन है, आपको कमांड प्रतिस्थापन को उद्धृत करने की आवश्यकता नहीं है। खोल वैरिएबल असाइनमेंट के लिए शब्द विभाजन नहीं करता है।

MYBASENAME=$(basename "$1") 

यह सब कुछ लेता है। आप बैकटिक के बजाय $() का उपयोग कर की आदत में मिल जाना चाहिए, क्योंकि अधिक आसानी से (यह POSIX है, btw, और सभी आधुनिक गोले यह समर्थन करते हैं।।)

पुनश्च $() घोंसले: आप करने के लिए नहीं लिखने बैश की कोशिश करनी चाहिए लिपियों । खोल स्क्रिप्ट लिखने का प्रयास करें। अंतर bashisms, zshisms, आदि की अनुपस्थिति है। बस सी के लिए, पोर्टेबिलिटी स्क्रिप्ट की वांछित विशेषता है, खासकर अगर इसे आसानी से प्राप्त किया जा सकता है। आपकी स्क्रिप्ट किसी भी bashisms का उपयोग नहीं करता है, इसलिए मैं इसके बजाय #!/bin/sh लिखूंगा। नाइट पिकर्स के लिए: हाँ, मुझे पता है, पुराना सनोस और सोलारिस /bin/sh$() समझ में नहीं आता है लेकिन /usr/xpg4/bin/sh एक पॉज़िक्स शैल है। कमांड प्रतिस्थापन के $() रूप का उपयोग करने के लिए

+0

मैंने देखा कि बहुत सारी डिफ़ॉल्ट शैल स्क्रिप्ट्स बैश के बजाय sh का उपयोग करती हैं।मैं अभी भी एक नई रेखा को दिखने से रोकने के लिए 'echo \ c' जैसी चीज़ों को छोड़कर, एक बहुत अंतर नहीं बता सकता। सुझावों और सहायक उत्तर के लिए धन्यवाद। – cwd

+0

echo \ c के साथ पोर्टेबल तरीका 'printf' का उपयोग करना है जहां आप प्रारूप स्ट्रिंग में' \ n' को छोड़ दें। सबसे अधिक उपयोग किए जाने वाले bashisms तर्कसंगत रूप से सरणी चर के उपयोग, गैर-पॉज़िक्स वाक्यविन्यास जैसे '[[...]] 'परीक्षण के लिए,' ((...)) 'के साथ लूप के लिए, और' चयन 'निर्माण । – Jens

+0

यह मेरे मैकॉक्स शेर (जीएनयू बैश, संस्करण 3.2.48 (1) -release (x86_64-apple-darwin11) – rjha94

4

समस्या यह है कि $1

में
MYBASENAME="`basename $1`" 

उद्धृत नहीं है। बजाय इस का उपयोग करें:

MYBASENAME="$(basename "$1")" 
+2

+1। जब तक आप वास्तव में नहीं हैं, वास्तव में, वास्तव में सुनिश्चित करें कि आप एक ऐसे सिस्टम का उपयोग करेंगे जिसमें केवल बोर्न शैल है, क्यों नहीं, अपने प्रौद्योगिकी वाक्यविन्यास को 1 99 3 के मानकों में अपग्रेड न करें ;-)! मैं शर्त लगाता हूं कि आप इसके बारे में सोचने के बिना 'sed -i' का उपयोग करें। लेकिन आपको उन प्रणालियों पर 'sed -i' नहीं मिलेगा जो बोर्न शैल, या 100 अन्य gnu/linux-isms पर भरोसा करते हैं। आप सभी को शुभकामनायें। <एंड PetPeeveRant /> – shellter

0
MYBASENAME="`basename $1`" 

MYBASENAME="`basename "$1"`" 

लपेटें $1 होना चाहिए दोहरे उद्धरण चिह्नों "$1"

2

आप उद्धरण के एक सेट से चूक रहे हैं के साथ!

MYBASENAME="`basename \"$1\"`" 

इससे आपकी समस्या ठीक हो जाएगी।

+0

आप कोट्स और बैकस्लैश की एक जोड़ी लिख रहे हैं :-) – Jens

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