2012-03-16 17 views
47

में टैब से अलग फ़ाइल लाइन पढ़ें, मैं एक फ़ाइल को लाइन द्वारा लाइन में एक स्क्रिप्ट में पढ़ना चाहूंगा। फ़ाइल में प्रत्येक पंक्ति एक टैब द्वारा अलग-अलग मान है, मैं प्रत्येक पंक्ति को सरणी में पढ़ना चाहता हूं।बैश: सरणी

विशिष्ट बैश "लाइन द्वारा फ़ाइल पढ़ें" उदाहरण;

while read line 
do 
echo $line; 
done < "myfile" 

मेरे लिए हालांकि, myFile इस (टैब सपरेटेड वैल्यू) की तरह दिखता है;

value1 value2 value3 
value4 value5 value6 

पाश से प्रत्येक यात्रा पर, मैं एक सरणी में जाने के लिए तो मैं

while read line into myArray 
do 
echo myArray[0] 
echo myArray[1] 
echo myArray[2] 
done < "myfile" 

यह मुद्रित होता कर सकते हैं पहले पाश यात्रा पर निम्नलिखित प्रत्येक पंक्ति चाहते हैं;

value1 
value2 
value3 

तो दूसरी यात्रा पर इसे प्रिंट होगा

value4 
value5 
value6 

यह संभव है? एकमात्र तरीका मैं देख सकता हूं कि मानों को मैन्युअल रूप से तोड़ने के लिए एक छोटा सा फ़ंक्शन लिखना है, क्या इसके लिए बैश में समर्थन में बनाया गया है?

उत्तर

99

तुम बहुत करीब हैं:

while IFS=$'\t' read -r -a myArray 
do 
echo "${myArray[0]}" 
echo "${myArray[1]}" 
echo "${myArray[2]}" 
done < myfile 

(-r बताता read कि \ इनपुट डेटा में विशेष नहीं है, -a myArray यह बताता शब्दों में इनपुट लाइन विभाजित है और में परिणाम स्टोर करने के लिए myArray; और IFS=$'\t' इसे नियमित रूप से बाश डिफ़ॉल्ट के बजाय शब्दों को विभाजित करने के लिए केवल टैब का उपयोग करने के लिए कहता है, जिससे रिक्त स्थान भी शब्दों को विभाजित करने की अनुमति देता है। ध्यान दें कि यह दृष्टिकोण एक या अधिक टैब को डेलीमीटर के रूप में मानता है, इसलिए यदि कोई है क्षेत्र खाली है, बाद में खेतों को पहले की स्थिति में "स्थानांतरित" किया जाएगा सरणी। क्या वह ओके है?)

+4

यह एक बढ़िया जवाब है, कि जैसे कि यह टूट के लिए धन्यवाद, मैं वास्तव में यह सराहना की। बस मुझे जो चाहिए, धन्यवाद: डी – jwbensley

6

यदि आप वास्तव में प्रत्येक शब्द (बैश अर्थ) को एक अलग सरणी इंडेक्स में विभाजित करना चाहते हैं तो लूप पुनरावृत्ति के दौरान प्रत्येक में सरणी को पूरी तरह से बदलना, @ ruakh का उत्तर सही दृष्टिकोण है। लेकिन आप पढ़ सकते हैं संपत्ति हर इस कोड स्निपेट

while IFS=$'\t' read -r column1 column2 column3 ; do 
    printf "%b\n" "column1<${column1}>" 
    printf "%b\n" "column2<${column2}>" 
    printf "%b\n" "column3<${column3}>" 
done < "myfile" 

सरणी सूचकांक पहुँच से बचने और सार्थक चर का उपयोग करके अपने कोड पठनीयता में सुधार के लिए एक समान परिणाम तक पहुंचने के लिए की तरह अलग अलग चर column1, column2 में शब्द, column3 पढ़ विभाजित करने के लिए उपयोग कर सकते हैं नाम (निश्चित रूप से columnN का उपयोग करना ऐसा करने का अच्छा विचार नहीं है)।

+0

वास्तविक रूप से 'gnrourf_gniourf द्वारा जोड़ा गया 'rr 'बैकस्लाश किए गए वर्णों के विस्तार से बचें, अगर '% b' को' printf' प्रारूप स्ट्रिंग में '% s' द्वारा प्रतिस्थापित किया जा सकता है तो बैकस्लाश किए गए कारणों का कारण बनता है पात्रों को शाब्दिक के रूप में दर्शाया जाएगा। तो, इसका उपयोग करें या नहीं, जो आप वास्तव में करना चाहते हैं उसके आधार पर। – slylittl3

0

आप भी आजमा सकते,

OIFS=$IFS; 
IFS="\t"; 

animals=`cat animals.txt` 
animalArray=$animals; 

for animal in $animalArray 
do 
    echo $animal 
done 

IFS=$OIFS; 
+0

'बिल्ली' का बेकार उपयोग लगता है http://stackoverflow.com/questions/11710552/useless-use-of-cat – jwbensley