बैश में एक सरणी में एक सीमांकित स्ट्रिंग पढ़ना


206

मेरे पास एक चर है जिसमें एक स्थान-सीमांकित स्ट्रिंग है:

line="1 1.50 string"

मैं उस स्ट्रिंग को एक सीमांकक के रूप में अंतरिक्ष में विभाजित करना चाहता हूं और परिणाम को एक सरणी में संग्रहीत करता हूं, ताकि निम्नलिखित हो:

echo ${arr[0]}
echo ${arr[1]}
echo ${arr[2]}

आउटपुट

1
1.50
string

कहीं मुझे एक समाधान मिला है जो काम नहीं करता है:

arr=$(echo ${line})

अगर मैं इसके बाद ऊपर दिए गए इको स्टेटमेंट को चलाता हूं, तो मुझे मिलता है:

1 1.50 string
[empty line]
[empty line]

मैंने भी कोशिश की

IFS=" "
arr=$(echo ${line})

उसी परिणाम के साथ। किसी की मदद कर सकते हैं, कृपया?


यूनिक्स और लिनक्स स्टैक एक्सचेंज पर इसका उत्तर देखें: हेरिंगिंग (<<<) और रीड-ए के साथ सेड का उपयोग करनाset -f; arr=($string); set +fसे तेज प्रतीत होता है read -r -a <<< $string
कोडफोर्स्टर

जवाबों:


331

स्ट्रिंग को एक सरणी में बदलने के लिए, कृपया उपयोग करें

arr=($line)

या

read -a arr <<< $line

यह महत्वपूर्ण है क्योंकि यह चाल नहीं है उद्धरण का उपयोग करें।


7
और अपने सुंदर नए सरणी की एक पवित्रता की जाँच करने के लिए:for i in ${arr[@]}; do echo $i; done
बंजर

5
या बसecho ${arr[@]}
बंजर

13
यदि $lineइसमें ग्लोबिंग वर्ण हैं, तो दोनों तरीके विफल हो सकते हैं । mkdir x && cd x && touch A B C && line="*" arr=($line); echo ${#arr[@]}3
टिनो

3
declare -a "arr=($line)"IFSउद्धृत स्ट्रिंग्स के अंदर सीमांकक को नजरअंदाज कर देगा
डेव

4
@Tino No. जब line='*', read -a arr <<<$lineहमेशा काम करते हैं, लेकिन केवल arr=($line)विफल रहता है।
जॉनी वोंग

39

इसे इस्तेमाल करे:

arr=(`echo ${line}`);

5
नाइस - यह समाधान Z शेल में भी काम करता है जहां ऊपर दिए गए कुछ अन्य दृष्टिकोण विफल हो जाते हैं।
कीथ ह्यूजिट

यह काम करता है, क्या आप बता सकते हैं कि यह क्यों काम करता है?
smartwjw

2
टिप्पणी: यह तब भी काम नहीं करता है जब रेखा में '*' हो, जैसेline='*'
जॉनी वोंग

34

में: arr=( $line )। "स्प्लिट" "ग्लोब" के साथ जुड़ा हुआ है।
वाइल्डकार्ड ( *, ?और []) मिलान फ़ाइल नाम के लिए विस्तार किया जाएगा।

सही समाधान केवल थोड़ा अधिक जटिल है:

IFS=' ' read -a arr <<< "$line"

ग्लोबिंग की समस्या नहीं; विभाजन चरित्र में $IFS, चर उद्धृत किया गया है।


5
यह स्वीकृत उत्तर होना चाहिए। स्वीकृत उत्तरarr=($line) में बयान ग्लोबिंग मुद्दों से ग्रस्त है। उदाहरण के लिए, कोशिश करें :। line="twinkling *"; arr=($line); declare -p arr
कोडपेस्टर

हेरिंग के लिए क्वोटिंग वैकल्पिक है, <<<लेकिन स्थिरता और पठनीयता के लिए दोहरे उद्धरण चिह्नों का उपयोग करना एक अच्छा विचार हो सकता है।
कोडपेस्टर

6

यदि आपको पैरामीटर विस्तार की आवश्यकता है, तो कोशिश करें:

eval "arr=($line)"

उदाहरण के लिए, निम्न कोड लें।

line='a b "c d" "*" *'
eval "arr=($line)"
for s in "${arr[@]}"; do 
    echo "$s"
done

यदि वर्तमान निर्देशिका में फ़ाइलें होती हैं a.txt, b.txtऔर c.txt, तो कोड को निष्पादित करने से निम्न आउटपुट का उत्पादन होगा।

a
b
c d
*
a.txt
b.txt
c.txt

-9
line="1 1.50 string"

arr=$( $line | tr " " "\n")

for x in $arr
do
echo "> [$x]"
done

लूपिंग गलत है, यह सरणी को ठीक से विभाजित करता है और पाइप में tr"${arr[@]}"$arr
अधिकता है
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.