बैश स्क्रिप्ट में वेरिएबल्स में नईलाइन कैसे जोड़ें


64

जब मैं करता हूं

str="Hello World\n===========\n"

मुझे इसका \nप्रिंट आउट भी मिल गया । फिर मैं कैसे नए अंक हो सकते हैं?


1
हालांकि यहाँ जवाब बहुत अच्छे हैं, लेकिन वास्तव में मुझे लगता है कि आप इस समय के लिए इस तरह की चीज़ के लिए एक सरणी का उपयोग करना बेहतर समझेंगे।
ev

जवाबों:


73

में bashआप वाक्य रचना का उपयोग कर सकते

str=$'Hello World\n===========\n'

एक से पहले एकल उद्धरण $एक नया वाक्यविन्यास है जो तार में भागने के दृश्यों को सम्मिलित करने की अनुमति देता है।

इसके अलावा printfबिलियन एक चर के लिए परिणामी उत्पादन को बचाने के लिए अनुमति देता है

printf -v str 'Hello World\n===========\n'

दोनों समाधानों को एक उपधारा की आवश्यकता नहीं है।

यदि निम्नलिखित में आपको स्ट्रिंग को प्रिंट करने की आवश्यकता है, तो आपको निम्नलिखित उदाहरण में, दोहरे उद्धरण चिह्नों का उपयोग करना चाहिए:

echo "$str"

क्योंकि जब आप स्ट्रिंग को बिना उद्धरण के प्रिंट करते हैं, तो newline रिक्त स्थान में परिवर्तित हो जाते हैं।


1
वाक्य रचना str=$'Hello World\n===========\n'को क्या कहा जाता है? चर प्रतिस्थापन?
zengr

5
@zengr: यह कहा जाता है एएनएसआई-सी के हवाले से , और यह भी में समर्थित है zshऔर ksh; हालाँकि, यह POSIX- अनुरूप नहीं है।
mklement0

4
@ mkelement0, यह ksh93 से आता है, इसे zsh, bash, mksh और FreeBSD sh द्वारा भी समर्थन किया जाता है, और POSIX के अगले प्रमुख संशोधन में इसका समावेश चर्चा में है
स्टीफन चेज़ेल

1
दोहरे उद्धरण चिह्नों के साथ काम करना प्रतीत नहीं होता है? जैसे str=$"My $PET eats:\n$PET food"? यह दृष्टिकोण दोहरे उद्धरण चिह्नों के लिए काम करता है
ब्रैड पार्क्स

31

आप सिंगल कोट्स (किसी बॉर्न / पोसिक्स-स्टाइल शेल में) के भीतर शाब्दिक नई रूपरेखाएँ डाल सकते हैं।

str='Hello World
===========
'

एक बहुस्तरीय स्ट्रिंग के लिए, यहां दस्तावेज़ अक्सर सुविधाजनक होते हैं। स्ट्रिंग को कमांड के इनपुट के रूप में खिलाया जाता है।

mycommand <<'EOF'
Hello World
===========
EOF

यदि आप स्ट्रिंग को एक चर में संग्रहीत करना चाहते हैं, तो catकमांड प्रतिस्थापन में कमांड का उपयोग करें । स्ट्रिंग के अंत में न्यूलाइन वर्ण (s) कमांड प्रतिस्थापन द्वारा छीन लिया जाएगा। यदि आप अंतिम newlines को बनाए रखना चाहते हैं, तो अंत में एक स्टॉपर लगाएं और बाद में इसे दूर करें। POSIX- आज्ञाकारी गोले में, आप str=$(cat <<'EOF'); str=${str%a}इसके बाद हेरेडोक उचित लिख सकते हैं , लेकिन बैश को बंद कोष्ठक के सामने आने की आवश्यकता है।

str=$(cat <<'EOF'
Hello World
===========
a
EOF
); str=${str%a}

Ksh, bash और zsh में, आप $'…'उद्धरण के अंदर बैकस्लैश एस्केप से बचने के लिए उद्धृत फॉर्म का उपयोग कर सकते हैं ।

str=$'Hello World\n===========\n'

1
मैं GNU बैश 4.1.5 का उपयोग कर रहा हूं, और str=$(cat <<'EOF')यह काम नहीं कर रहा है-के रूप में .. )एंड-ऑफ-डॉक के बाद अगली पंक्ति में रखे जाने की आवश्यकता है EOF.. लेकिन फिर भी, यह कमांड के कारण अनुगामी न्यूलाइन खो देता है प्रतिस्थापन।
पीटर.ओ।

@ अच्छा अंक, मैंने अनुगामी newlines के बारे में समझाया है और कोड दिखाया है जो काम करता है। मुझे लगता है कि यह बैश में एक बग है, हालांकि POSIX कल्पना की पुनरावृत्ति करने पर ईमानदार होने के लिए मुझे यह स्पष्ट नहीं है कि व्यवहार अनिवार्य है जब << एक कमांड प्रतिस्थापन के अंदर है और heredoc नहीं है।
गिलीस

उत्तम सामग्री; एक चर में यहाँ-डॉक्टर को कैप्चर करते समय अनुगामी (और अग्रणी) \nउदाहरणों को संरक्षित करने के लिए, डॉपर दृष्टिकोण के विकल्प के रूप में bashविचार करें IFS= read -r -d '' str <<'EOF'...(मेरा उत्तर देखें)।
15:27 पर mklement0

8

क्या आप "इको" का उपयोग कर रहे हैं? "इको-ई" का प्रयास करें।

echo -e "Hello World\n===========\n"

2
Btw। आपको अंतिम \ n की आवश्यकता नहीं है, क्योंकि echoजब तक आप निर्दिष्ट नहीं करते, तब तक स्वचालित रूप से एक जोड़ दिया जाएगा। (हालांकि, सवाल का मुख्य खामियाजा यह है कि इन न्यूलाइन्स को वेरिएबल में कैसे लाया जाए)।
पीटर।

सभी समाधानों में से +1, यह सबसे प्रत्यक्ष और सरल है।
हाई वू

इको-ओएस OS में काम नहीं करता है
ग्रेग एम। क्रैसक

2
@GregKrsak: में bash, OS X पर काम echo -e करता है - ऐसा इसलिए echoहै क्योंकि एक बैश बिलिन (बाहरी निष्पादन योग्य के बजाय) है और यह बिलिन समर्थन करता है -e। (एक बिल्डिन के रूप में, यह उन सभी प्लेटफार्मों पर काम करना चाहिए, जो इस पर चलते हैं; संयोगवश, और भी बहुत से echo -eकाम करते हैं)। इसके विपरीत, हालांकि, ओएस एक्स पर बाहरी उपयोगिता - - वास्तव में समर्थन नहीं करती है । kshzshecho/bin/echo-e
mklement0

3

यदि आपको अपनी स्क्रिप्ट में कई बार नई सुर्खियों की आवश्यकता होती है तो आप एक ग्लोबल वैरिएबल की घोषणा कर सकते हैं। इस तरह से आप इसे दोहरे-उद्धृत स्ट्रिंग्स (चर विस्तार) में उपयोग कर सकते हैं।

NL=$'\n'
str="Hello World${NL} and here is a variable $PATH ===========${NL}"

$''एक उपधारा की आवश्यकता क्यों होगी ?
Mat

क्षमा करें, मैंने एक उत्तर गलत दिया है।
पिहंगाग्नि

क्या मैं डाउनवोटर्स से स्पष्टीकरण मांग सकता हूं?
पाइयेंटैगी

अच्छा! यह दोहरे उद्धरण चिह्नों का उपयोग करके चर में शामिल किया जा सकता है, जैसे"My dog eats:${NL}dog food"
ब्रैड पार्क्स

3

सभी चर्चा से, यहाँ मेरे लिए सबसे सरल तरीका है:

bash$ str="Hello World
==========="
bash$ echo "$str"
Hello World
===========

गूंज आदेश का उपयोग करना चाहिए डबल कोट्स


3

महान मौजूदा उत्तरों के पूरक के लिए:

यदि आप उपयोग कर रहे हैं bashऔर आप पठनीयता के लिए वास्तविक नईलाइन्स का उपयोग करना पसंद करते हैं , readतो एक चर में यहाँ-डॉक्टर को कैप्चर करने के लिए एक और विकल्प है , जो (यहाँ अन्य समाधानों की तरह) एक सब-हेल्प के उपयोग की आवश्यकता नहीं है।

# Reads a here-doc, trimming leading and trailing whitespace.
# Use `IFS= read ...` to preserve it (the trailing \n, here).
read -r -d '' str <<'EOF'   # Use `IFS= read ...` to preserve the trailing \n
Hello World
===========
EOF
# Test: output the variable enclosed in "[...]", to show the value's boundaries.
$ echo "$str"
[Hello World
===========]
  • -rयह सुनिश्चित करता है कि readइनपुट की व्याख्या नहीं करता है (डिफ़ॉल्ट रूप से, यह बैकस्लैश विशेष का इलाज करेगा, लेकिन इसकी आवश्यकता शायद ही हो)।

  • -d ''एक खाली स्ट्रिंग में "रिकॉर्ड" सीमांकक सेट करता है, जिससे एक ही बार में (केवल एक पंक्ति के बजाय) पूरे इनपुट readको पढ़ा जा सकता है ।

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

आमतौर पर, यह वांछित व्यवहार होता है, लेकिन यदि आप चाहते हैं कि अनुगामी न्यूलाइन, IFS= read -r -d ''केवल के बजाय का उपयोग करें read -r -d '', लेकिन ध्यान दें कि किसी भी अग्रणी और अनुगामी व्हाट्सएप को तब संरक्षित किया जाता है।
(ध्यान दें कि IFS= सीधे readकमांड को प्रस्तुत करने का अर्थ है कि असाइनमेंट केवल उस कमांड के दौरान प्रभावी है, इसलिए पिछले मान को पुनर्स्थापित करने की कोई आवश्यकता नहीं है।)


यहाँ-डॉक का उपयोग करने से आपको पठनीयता के लिए बहुस्तरीय स्ट्रिंग को सेट करने के लिए वैकल्पिक रूप से इंडेंटेशन का उपयोग करने की अनुमति मिलती है:

# Caveat: indentation must be actual *tab* characters - spaces won't work.
read -r -d '' str <<-'EOF' # NOTE: Only works if the indentation uses actual tab (\t) chars.
    Hello World
    ===========
EOF
# Output the variable enclosed in "[...]", to show the value's boundaries.
# Note how the leading tabs were stripped.
$ echo "$str"
[Hello World
===========]

के -बीच रखने <<और यहाँ खोलने-डॉक्टर delimiter ( 'EOF', यहाँ) प्रमुख टैब वर्ण यहाँ-डॉक्टर शरीर और यहां तक ​​कि समापन सीमांकक से छीनने का कारण बनता है, लेकिन ध्यान दें कि यह केवल वास्तविक टैब वर्णों के साथ काम करता है , न कि रिक्त स्थान, इसलिए आपके संपादक टैब के कीपेस को रिक्त स्थान में बदल देता है, अतिरिक्त काम की जरूरत होती है।


-1

आपको इसे इस तरह से करने की आवश्यकता है:

STR=$(echo -ne "Hello World\n===========\n")

अपडेट करें:

जैसा कि फ्रेड ने बताया, इस तरह आप "\ n" को पीछे छोड़ देंगे। विस्तारित बैकस्लैश दृश्यों के साथ परिवर्तनशील असाइन करने के लिए, करें:

STR=$'Hello World\n===========\n\n'

आइए इसका परीक्षण करें:

echo "[[$STR]]"

अब हमें देता है:

[[Hello World
===========

]]

ध्यान दें, कि $ '' $ "से भिन्न है।" दूसरा वर्तमान स्थान के अनुसार अनुवाद करता है। डीटेल के लिए क्वोटिंग सेक्शन में देखें man bash


-2
#!/bin/bash

result=""

foo="FOO"
bar="BAR"

result+=$(printf '%s' "$foo")$'\n'
result+=$(printf '%s' "$bar")$'\n'

echo "$result"
printf '%s' "$result"

उत्पादन:

FOO
BAR

FOO
BAR

1
बस क्यों नहीं result+=$foo$'\n'? यदि कोई हो तो $(printf %s "$foo")अनुगामी न्यूलाइन वर्ण को ट्रिम कर देगा $foo
स्टीफन चेजलस

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