कैसे एक स्ट्रिंग में विशेष पात्रों से बचने के लिए?


16

मान लें कि $fileफ़ाइल नाम का मान है, तो कहें Dr' A.tif। बैश प्रोग्रामिंग में, मैं विशेष चरित्र $fileको हटाए बिना एकल उद्धरण और किसी अन्य विशेष चरित्र से कैसे बच सकता हूं ?

अद्यतन 9 जुलाई 2014 को

के रूप में @Gilles से अनुरोध , कोड स्निपेट कि संभाल करने में सक्षम नहीं है निम्नलिखित Dr' A.tif:

files=$(find /path/ -maxdepth 1 -name "*.[Pp][Dd][Ff]" -o -name "*.[Tt][Ii][Ff]")
echo "${files}" > ${TEMP_FILE}
while read file
do
   newfile=$(echo "${file}" | sed 's, ,\\ ,g') ## line 1
done < ${TEMP_FILE}

बाद मैं बाहर की कोशिश की है @Patrick से जवाब पर line 1, यह मेरे लिए काम करने लगता है। लेकिन अगर मेरे पास ऐसी फाइल है Dr\^s A.tif, तो printfकमांड मदद नहीं करता है, यह मुझे दिखाता है Dr\^s\ A.tif। अगर मैं स्वयं इसे इस तरह कंसोल पर आज़माता हूँ:

printf "%q" "Dr\^s A.tif"

मेरे पास यह आउटपुट होगा:

Dr\\\^s\ A.tif

किसी भी विचार यह कैसे संभालना है?


3
आप किस संदर्भ में $ फ़ाइल का उपयोग करने की उम्मीद कर रहे हैं? या यह मुद्दा विशेष फ़ाइल के साथ स्ट्रिंग को $ फ़ाइल में निर्दिष्ट कर रहा है?
लूटने

वास्तव में खोज आदेश मुझे फ़ाइल सूची की एक सरणी लौटाता है। और फिर मैं इस फ़ाइल सूची के माध्यम से $ फ़ाइल चर में लूप करता हूं।
हुहसिन 68

2
आपको यहाँ कुछ सही उत्तर दिए गए हैं, लेकिन वे शायद उस प्रश्न के उत्तर नहीं हैं जो आप वास्तव में पूछ रहे हैं। यहाँ आपकी टिप्पणी से, मुझे दृढ़ता से संदेह है कि आप गलत रास्ते पर हैं। हम आपकी बहुत मदद नहीं कर सकते क्योंकि आप अपना कोड नहीं दिखा रहे हैं। मैं हालांकि यह सलाह देता हूं कि आप पढ़ें कि मेरी शेल स्क्रिप्ट व्हॉट्सएप या अन्य विशेष पात्रों पर क्यों चोक करती है? पृष्ठभूमि के रूप में। अपनी स्क्रिप्ट दिखाएं और समझाएं कि आप क्या करना चाहते हैं।
गिल्स एसओ- बुराई को रोकें '

जवाबों:


14

इसे पूरा करने के लिए आप printfबिलिन का उपयोग कर सकते हैं %q। उदाहरण के लिए:

$ file="Dr' A.tif"
$ printf '%q\n' "$file"
Dr\'\ A.tif

$ file=' foo$bar\baz`'
$ printf '%q\n' "$file"
\ foo\$bar\\baz\`

पर बैश प्रलेखन से printf:

In addition to the standard format specifications described in printf(1)
and printf(3), printf interprets:

 %b       expand backslash escape sequences in the corresponding argument
 %q       quote the argument in a way that can be reused as shell input
 %(fmt)T  output the date-time string resulting from using FMT as a format
          string for strftime(3)

यह कुछ मामलों के साथ काम नहीं करता है। जब आपको डबल-कोट्स को संरक्षित करने की आवश्यकता होती है।
user3467349

@ user3467349 यह उद्धरण के साथ ठीक काम करता है। मुझे यकीन है आप कुछ पसंद कर रहे हैं printf '%s' "foo"। आपको यह समझने की जरूरत है कि पहले शेल में तर्क कैसे काम करता है। Gnu.org/software/bash/manual/bash.html#Shell-Operation # 2 देखें # 6 से पहले होता है।
पैट्रिक

क्या आप इस स्ट्रिंग का एक उदाहरण प्रदान कर सकते हैं, जिसके साथ printfकोई अन्य जोड़तोड़ नहीं हैIt doesn't have a: ""
उपयोगकर्ता 3467349

आपके मुद्दे का कोई लेना-देना नहीं है printf। आपका मुद्दा यह है कि आप अपने स्ट्रिंग को पार्स नहीं करना चाहते हैं। ऐसा करने के लिए, आपको अपने इनपुट को शेल में इस तरह से पास करना होगा जहां वह इसे पार्स करने का प्रयास भी नहीं करता है। ऐसा करने का एक तरीका होगा read -r -p 'input: ' && printf '%q\n' "$REPLY", और संकेत दिए जाने पर इनपुट प्रदान करें।
पैट्रिक

1
जैसा कि मैंने अब कई बार कहा है। शेल के लिए कच्चे डेटा को कैसे पास किया जाए, यह नहीं पता है printf। शायद आपको ऐसे समाधान की आलोचना करने के बजाय एक सवाल पूछना चाहिए जिसका आपकी समस्या से कोई लेना-देना नहीं है।
पैट्रिक

4

प्रयत्न:-

file=Dr\'\ A.tif
echo $file
Dr' A.tif

या

file="Dr' A.tif"
echo $file
Dr' A.tif

या यदि स्ट्रिंग में एक डबल उद्धरण है: -

file='Dr" A.tif'
echo $file
Dr" A.tif

नेट पर भागने और उद्धृत करने के अच्छे ट्यूटोरियल हैं। इस एक के साथ शुरू करो ।


1

आपको किसी भी फ़ाइल नाम से बचने की ज़रूरत नहीं है जिसे आप किसी स्क्रिप्ट में संभाल रहे हैं। बचना तभी आवश्यक है जब आप किसी स्क्रिप्ट में एक फ़ाइल नाम को शाब्दिक के रूप में रखना चाहते हैं , या एक स्क्रिप्ट के लिए एक इनपुट स्ट्रीम के रूप में कई फ़ाइल नामों को पास करना चाहते हैं।

चूंकि आप आउटपुट के माध्यम से लूप कर रहे हैं find, यह हर संभव पथ को संभालने के लिए सबसे सरल तरीकों (!) में से एक है :

while IFS= read -r -d ''
do
    file_namex="$(basename -- "$REPLY"; echo x)"
    file_name="${file_namex%$'\nx'}"
    do_something -- "$file_name"
done <(find "$some_path" -exec printf '%s\0' {} +)


-1

इनमें से बहुत से जवाबों का उपयोग करने वाले शीर्ष मतदाता printf "%q"अतिरिक्त हेरफेर के बिना सभी मामलों में काम नहीं करेंगे। मैं निम्नलिखित सुझाव दूंगा (नीचे उदाहरण):

cat <<EOF; 2015-11-07T03:34:41Z app[postgres.0000]: [TAG] text-search query doesn't contain lexemes: "" EOF


N00b प्रश्न को माफ करें, लेकिन क्या आप इस बात पर विस्तार से बता सकते हैं कि एक स्ट्रिंग में वर्णों से बचने के लिए आप वास्तव में इसका उपयोग कैसे करेंगे? अगर आप मेरे टर्मिनल में लिखे गए कोड को कॉपी करते हैं तो यह सिर्फ 2015-11-07T03: 34: 41Z ऐप [postgres.0000] प्रिंट करता है: [TAG] टेक्स्ट-सर्च क्वेरी में lexemes नहीं है: "" ... कुछ भी नहीं बचा है ।
शार्कअली

यह शाब्दिक बिंदु है, सभी विशेष वर्णों की व्याख्या शाब्दिक वर्णों के रूप में की जाती है, न कि उनके विशेष अर्थ के लिए। अंतर देखने के बजाय "उपरोक्त स्ट्रिंग" को प्रतिध्वनित करने का प्रयास करें ।
user3467349
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.