2012-03-16 46 views
47

我想將文件逐行讀入腳本。文件中的每行都有一個由製表符分隔的多個值,我想將每行讀入一個數組。Bash:將製表符分隔的文件行讀入數組

典型bash「逐行讀取文件」示例;

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 

這可能嗎?我能看到的唯一方法是編寫一個小函數來手動分離值,在bash中是否支持這個功能?

回答

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'告訴它只使用製表符來分割單詞,而不是常規的Bash默認值也允許空格分割單詞。注意,這種方法將把一個或更多的製表符作爲分隔符,所以如果有的話領域是空白的,後面的領域將被「轉移」到更早的位置陣列。那是O.K.?)

+4

這是一個偉大的回答,感謝其分解那樣,我真的很感激它。正是我所需要的,謝謝:D – jwbensley 2012-03-16 12:19:17

6

如果你真的想把每個單詞(bash意思)拆分成一個完全不同的數組索引,並在每個循環迭代中完全改變數組,那麼@ ruakh的答案是正確的方法。但是你可以使用讀取屬性拆分每次讀字成不同的變量column1column2column3想在這個代碼片段

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" 

達到類似的效果,避免數組索引訪問和使用有意義的變量改進代碼的可讀性名稱(當然使用columnN不是一個好主意)。

+0

實際上@gniourf_gniourf添加了'-r'來避免擴展反斜槓的字符,如果'%b'能被'printf'格式的'%s'替代,字符串會導致反斜槓被掃描字符將被表示爲文字。所以,根據你真正想做什麼來使用它或不使用它。 – slylittl3 2015-02-19 02:05:51

0

您也可以嘗試,

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

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

for animal in $animalArray 
do 
    echo $animal 
done 

IFS=$OIFS; 
+0

似乎是'cat'的無用用法http://stackoverflow.com/questions/11710552/useless-use-of-cat – jwbensley 2017-04-19 06:59:57

相關問題