गूंज मेरे उद्धरण पात्रों की उपेक्षा क्यों कर रही है?


24

echoआदेश पूरा पाठ है कि मैं इसे देने सहित नहीं है। उदाहरण के लिए, अगर मैं करता हूं:

   $ echo ' echo PARAM=`  grep  $ARG  /var/tmp/setfile  | awk '{print $2}' `    '

यह आउटपुट:

echo PARAM=`  grep  $ARG  /var/tmp/setfile  | awk {print } `

'मेरी प्रतिध्वनि कमांड में मेरे द्वारा लिए गए एकल उद्धरण ( ) शामिल नहीं हैं। यदि मैं दोहरे उद्धरण चिह्नों पर जाता हूं:

$ echo " echo PARAM=`  grep  $ARG  /var/tmp/setfile  | awk '{print $2}' `  "

echoकुछ भी उत्पादन नहीं करता है! यह पहले उदाहरण में एकल उद्धरण क्यों छोड़ रहा है और दूसरे में कुछ भी आउटपुट नहीं कर रहा है? मैं इसे कैसे टाइप कर सकता हूँ जैसा मैंने लिखा था?


3
यकीन नहीं होता कि आप यहां क्या हासिल करने की कोशिश कर रहे हैं। आप दूसरे में एक प्रतिध्वनि बयान क्यों कर रहे हैं? या क्या आप सचमुच एक कमांड को प्रिंट करने की कोशिश कर रहे हैं (उदाहरण के लिए या ऐसे)?
एंडी स्मिथ

मुझे दूसरी फाइल में इको आउटपुट डालने की आवश्यकता है

आपको यह समझाने की आवश्यकता है कि आप क्या करने की कोशिश कर रहे हैं। जैसे "मैं निम्नलिखित पाठ को संलग्न करना चाहता हूं: '...' एक फाइल में।"
मिकीबी

2
मैं इसे 5 मिनट के लिए संपादित करने की कोशिश कर रहा हूं, लेकिन मैं गंभीरता से नहीं जानता कि वांछित आउटपुट क्या है। संपादित करें : ठीक है, मुझे लगता है कि मेरे पास अभी एक अनुमान है, इसलिए मैंने संपादन की कोशिश की। यदि ऐसा नहीं है कि तुम क्या मुझे पता है इरादा
माइकल Mrozek

1
@ मिचेल - वाह - अगर मैं आपको अपने संपादन के लिए कुछ प्रतिनिधि दे सकता था, तो मैं - अच्छा काम यह एक बहुत अच्छा सवाल बना सकता है!
रान्डेल

जवाबों:


33

आपके खोल उद्धरणों की व्याख्या कर रहे हैं, दोनों 'और ", इससे पहले कि वे भी प्राप्त करें echo। मैं आमतौर पर अपने तर्क के इर्द-गिर्द दोहरा उद्धरण लगाता हूं, भले ही वे अनावश्यक हों; उदाहरण के लिए:

$ echo "Hello world"
Hello world

इसलिए अपने पहले उदाहरण में, यदि आप अपने आउटपुट में शाब्दिक उद्धरण चिह्नों को शामिल करना चाहते हैं, तो उन्हें या तो बच जाना चाहिए:

$ echo \'Hello world\'
'Hello world'

या उन्हें पहले से ही एक उद्धृत तर्क के भीतर उपयोग करने की आवश्यकता है (लेकिन यह उसी तरह का उद्धरण नहीं हो सकता है, या आपको इसे वैसे भी बचने की आवश्यकता होगी):

$ echo "'Hello world'"
'Hello world'

$ echo '"Hello world"'
"Hello world"

अपने दूसरे उदाहरण में, आप स्ट्रिंग के बीच में कमांड प्रतिस्थापन चला रहे हैं:

grep  $ARG  /var/tmp/setfile  | awk {print $2}

$जिन चीजों के साथ शुरुआत होती है उन्हें विशेष रूप से शेल द्वारा नियंत्रित किया जाता है - यह उन्हें चर के रूप में मानता है और उन्हें अपने मूल्यों के साथ बदल देता है। चूँकि सबसे अधिक संभावना है कि उनमें से कोई भी चर आपके शेल में सेट नहीं है, यह वास्तव में बस चलता है

grep /var/tmp/setfile | awk {print}

चूँकि grepकेवल एक तर्क को देखता है, यह मानता है कि तर्क वह पैटर्न है जिसे आप खोज रहे हैं, और यह कि जिस स्थान से इसे डेटा पढ़ना चाहिए वह स्टडिन है, इसलिए यह इनपुट की प्रतीक्षा कर रहा है। इसलिए आपका दूसरा कमांड सिर्फ लटका हुआ प्रतीत होता है।

यदि आप तर्क को एकल-उद्धरण करते हैं (तो यही कारण है कि आपका पहला उदाहरण लगभग काम किया है) तो ऐसा नहीं होगा, इसलिए यह वह तरीका है जो आपको प्राप्त होता है:

echo \'' echo PARAM=`  grep  $ARG  /var/tmp/setfile  | awk '{print $2}' `    '\'

आप इसे डबल-कोट भी कर सकते हैं, लेकिन फिर आपको $एस से बचना होगा इसलिए शेल उन्हें चर के रूप में हल नहीं करता है, और बैकटिक्स इसलिए शेल कमांड प्रतिस्थापन को तुरंत नहीं चलाता है:

echo "' echo PARAM=\`  grep  \$ARG  /var/tmp/setfile  | awk '{print \$2}' \`    '"

7

मैं इस बात पर अधिक विस्तार में नहीं जा रहा हूं कि आपके प्रयासों से उनके काम करने के तरीके का व्यवहार होता है, क्योंकि माइकल मर्ज़ेक का जवाब यह अच्छी तरह से कवर करता है। संक्षेप में, एकल उद्धरण के बीच सब कुछ ( '…') का शाब्दिक (और विशेष रूप से पहले में व्याख्या की है 'निशान शाब्दिक स्ट्रिंग के अंत), जबकि `और $के बीच उनके विशेष अर्थ को बनाए रखने "…"

एकल उद्धरणों में कोई उद्धरण नहीं है, इसलिए आप एकल-उद्धृत स्ट्रिंग के अंदर एक भी उद्धरण नहीं डाल सकते हैं। वहाँ एक मुहावरा है जो ऐसा दिखता है:

echo 'foo'\''bar'

यह प्रिंट करता है foo'bar, क्योंकि तर्क echoएकल-उद्धृत तीन-वर्ण स्ट्रिंग से बना है foo, एकल वर्ण के साथ संक्षिप्त '( 'पूर्ववर्ती के माध्यम से अपने विशेष अर्थ से चरित्र की रक्षा करके प्राप्त \), एकल-उद्धृत तीन-वर्ण स्ट्रिंग के साथ bar। इसलिए यद्यपि यह काफी नहीं है कि पर्दे के पीछे क्या होता है, आप '\''एकल-उद्धरण स्ट्रिंग के अंदर एक एकल उद्धरण को शामिल करने के तरीके के रूप में सोच सकते हैं ।

यदि आप जटिल मल्टीलाइन स्ट्रिंग्स को प्रिंट करना चाहते हैं, तो एक बेहतर टूल यहां दस्तावेज़ है । यहाँ एक दस्तावेज़ में दो अक्षर होते हैं <<जैसे कि एक मार्कर <<EOF, उसके बाद पाठ की कुछ पंक्तियाँ, फिर अंत में अपनी लाइन पर अकेला मार्कर। मार्कर (किसी भी तरह से उद्धृत किया गया है, तो 'EOF'या "EOF"या \EOFया 'ई "" का' या ...), तो पाठ का शाब्दिक (एकल, कोट के अंदर की तरह, सिवाय इसके कि यहां तक कि व्याख्या की है 'एक साधारण चरित्र है)। यदि मार्कर को बिल्कुल उद्धृत नहीं किया जाता है, तो पाठ की व्याख्या डबल-उद्धृत स्ट्रिंग की तरह की जाती है, जिसमें $\`उनकी विशेष स्थिति को बनाए रखा जाता है (लेकिन "और नए शब्दों की शाब्दिक व्याख्या की जाती है)।

cat <<'EOF'
echo PARAM=`  grep  $ARG  /var/tmp/setfile  | awk '{print $2}' `
EOF

1

ठीक है, यह काम करेगा: -

echo ' echo PARAM=`  grep  $ARG  /var/tmp/setfile  | awk '\''{print $2}'\'' `    '

इसे यहाँ परीक्षण: -

[asmith@yagi ~]$ echo ' echo PARAM=`  grep  $ARG  /var/tmp/setfile  | awk '\''{print $2}'\'' `    '
 echo PARAM=`  grep  $ARG  /var/tmp/setfile  | awk '{print $2}' ` 

0

यहाँ एक दस्तावेज़ का उपयोग करने का गिल्स का सुझाव वास्तव में अच्छा है, और यहां तक ​​कि पर्ल जैसी स्क्रिप्टिंग भाषाओं के भीतर भी काम करता है। ओपी के मुद्दे पर उनके जवाब के आधार पर एक विशिष्ट उदाहरण के रूप में,

use strict;
my $cmd = q#cat <<'EOF' # . "\n" .
          q#echo PARAM=`  grep  $ARG  /var/tmp/setfile  | awk '{print $2}' `# . "\n" .
          q#EOF# ;
open (my $OUTPUT, "$cmd |");
print $_ while <$OUTPUT>;
close $OUTPUT;

दी, यह उदाहरण थोड़ा विवादित है, लेकिन मैंने इसे psql(इसके बजाय cat) एसक्यूएल स्टेटमेंट भेजने के लिए एक उपयोगी तकनीक के रूप में पाया है ।

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


-1

आइए आपकी आज्ञा लेते हैं

$ echo ' echo PARAM=`  grep  $ARG  /var/tmp/setfile  | awk '{print $2}' `    '

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

Arg[1]=“' echo PARAM=`  grep  $ARG  /var/tmp/setfile  | awk '{print”
Arg[2]=“$2}' `    '”

अगला, हम पैरामीटर विस्तार करते हैं: विस्तार करें $…लेकिन अंदर नहीं '…'। चूंकि $2खाली है (जब तक आप इसे उदाहरण के माध्यम से सेट नहीं करते हैं set -- …), इसे एक खाली स्ट्रिंग द्वारा बदल दिया जाएगा।

Arg[1]=“' echo PARAM=`  grep  $ARG  /var/tmp/setfile  | awk '{print”
Arg[2]=“}' `    '”

इसके बाद, उद्धरण हटाएं।

Arg[1]=“ echo PARAM=`  grep  $ARG  /var/tmp/setfile  | awk {print”
Arg[2]=“} `    ”

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

“ echo PARAM=`  grep  $ARG  /var/tmp/setfile  | awk {print } `    ”

मुझे उम्मीद है कि यह चरण-दर-चरण निर्देश मनाया व्यवहार को स्पष्ट करता है। इस समस्या से बचने के लिए, इस तरह एकल उद्धरण से बचिए:

$ echo ' echo PARAM=`  grep  $ARG  /var/tmp/setfile  | awk '\''{print $2}'\'' `    '

यह एकल-उद्धृत स्ट्रिंग को समाप्त कर देगा, फिर शब्द में एक (बच गया) एकल उद्धरण जोड़ें, फिर एक नया एकल-उद्धृत स्ट्रिंग प्रारंभ करें, सभी शब्द को अलग किए बिना।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.