2012-03-16 25 views
47

dizisine oku Bir dosyayı bir satırda satır satır satırında okumak istiyorum. Dosyadaki her satır bir sekmeyle ayrılmış birden çok değerdir, her satırı bir diziye okumak isterim.Bash: Sekme ile ayrılmış dosya satırını

Tipik bash "satırda dosya oku" örneği; Benim için

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

olsa dosyam bu (sekme ayrılmış değerler) benziyor;

her döngü tekrarında günü
value1 value2 value3 
value4 value5 value6 

, ben bu yüzden

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

bu ilk döngü yineleme aşağıdaki basacaktır olabilir bir diziye girmek, her satırı istiyorum;

value1 
value2 
value3 

Sonra ikinci tekrarında bu

value4 
value5 
value6 

bu mümkün mü basacaktır? Görebilmemin tek yolu, değerleri el ile kesmek için küçük bir işlev yazmaktır, bunun için bash'ta destek var mı?

cevap

99

Çok yakınsın:

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

(-r\ giriş verilerinde özel değil read söyler; -a myArray kelimelere girdi satırı bölmek ve sonuçları saklamak için söyler myArray ve IFS=$'\t', boşlukları sözcükleri de ayırmalarına izin veren normal Bash varsayılanı yerine yalnızca sözcükleri bölmek için sekmeleri kullanmasını söyler.Bu yaklaşımın bir veya daha fazla sekmeyi sınırlayıcı olarak ele alacağını unutmayın. alan boş, daha sonra alanlar daha önceki konumlara "kaydırılır" dizi. Bu, O ?.

+4

Bu büyük bir cevabı, bunu böyle parçalayarak için teşekkürler, gerçekten takdir. Sadece ihtiyacım olan şey, teşekkürler: D – jwbensley

6

Her kelimeyi (bash anlamını) her zaman döngü yinelemesinde diziyi tamamen değiştiren farklı bir dizine bölmek istiyorsanız, @ ruakh yanıtı doğru yaklaşımdır. Ama Her dizi indeksi erişimini kaçınarak ve anlamlı değişken kullanarak kod okunabilirliğini arttırmak benzer bir sonuca ulaşmak için

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" 

bu kod parçacığı gibi farklı değişkenlerin column1, column2 içine sözcüğü, column3 okumak bölmek için okunan özelliğini kullanabilirsiniz isimleri (elbette columnN kullanarak yapmak iyi bir fikir değildir).

+0

Aslında '-r' tarafından eklenen @gniourf_gniourf, ters eğik çizgi karakterlerinin genişlemesini önler, eğer bunu yaparsanız, "% s", "printf" biçimindeki "% s" ile değiştirilebiliyorsa, ters eğik çizgi Karakterler değişmez olarak temsil edilecektir. Öyleyse, ne yapmak istediğinize bağlı olarak kullanın ya da kullanmayın. – slylittl3

0

Şunu da deneyebilirsiniz,

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

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

for animal in $animalArray 
do 
    echo $animal 
done 

IFS=$OIFS; 
+0

"Kedi" nin işe yaramaz bir kullanımı gibi görünüyor http://stackoverflow.com/questions/11710552/useless-use-of-cat – jwbensley

İlgili konular