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


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.