2012-05-25 2 views
-2

Если у меня есть файл, как это:массив из файла

A:a 
B:b 
C:c 

Мне нужно создать 2 массивы, как

one=('A' 'B' 'C') 
two=('a' 'b' 'c') 

Как я могу сделать это в Баш?

Я попытался это:

declare -a one 
declare -a two 

while read line 
do 
    IFS=':' read -ra ADDR <<< $line 
    echo ${ADDR[0]} 
    echo ${ADDR[1]} 
done < file.txt 

К сожалению, я писал с работы, а потом я пришел домой. Еще раз извините. Проблема с этим состоит в том, что это печать

littlelion:Documents dierre$ sh prova.sh 
A a 

B b 

так не хватает C C, и я понятия не имею, как добавить элемент в массив

+0

вы не используете свой 'declare -a one (& two)' s. Похоже, это поможет. Кроме того, поскольку вы используете IFS =:, почему бы не читать 'tmpOne tmpTwo; ...' И вам не нужно '<<< $ line'. Затем сделайте что-то вроде 'one = ($ {one [@]} $ tmpOne)' ... и т. Д., Но вы можете понять это ;-) (Вот почему это комментарий). Удачи! – shellter

ответ

3

Цитаты исправить все:

while read line 
do 
    IFS=':' read -ra ADDR <<< "$line" 
    echo ${ADDR[0]} 
    echo ${ADDR[1]} 
done < file.txt 

Цитирование переменной "$line" - это то, что сделало разницу. Если вы не получаете строку с «C: c», это, вероятно, потому, что в вашем файле отсутствует окончательная новая строка.

0

Использование Command Substitution:

declare -a one 
declare -a two 

one=($(cut -d: -f1 file)) 
two=($(cut -d: -f2 file)) 

var=$(command) захватывает вывода вашей команды и назначает ее var. Внешний parens делает это назначение массива. cut -d: -f1 говорит, что обрабатывает файл как файл с разделителями двоеточия и печатает первое поле. cut -d: -f2 делает то же самое, но печатает второе поле.


Редактировать в ответ на редактирование параметров порядка

Вы можете прочитать в ADDR прямо так:

declare -a ADDR 
while IFS=':' read -a ADDR; do 
    echo ${ADDR[0]} 
    echo ${ADDR[1]} 
done < file.txt 

Хотя это не заполнит массивы one и two ...

+0

Это, вероятно, будет работать, но было бы нецелесообразно прокручивать файл дважды, если это большой файл. – gpojd

+0

ОК, но один и два не массивы с разрезом. Я ошибаюсь? – dierre

+0

@gpojd Очень оптимизированный, нет, но он короткий. Я бы предпочел это для файлов с небольшим и средним размером. –

0

Если я понимаю, что вы пытаетесь сделать правильно, это должно работать:

one=() 
two=() 
while IFS=: read new_one new_two || [ -n "$new_one" ]; do 
    one+=("$new_one") 
    two+=("$new_two") 
done 
echo "one:" "${one[@]}" 
echo "two:" "${two[@]}" 

Примечание: Я согласен с @Dennis Williamson, что последняя строка не обрабатывается, потому что она не заканчивается с новой строкой; Я добавил бит || [ -n "$new_one" ], чтобы это не было проблемой.

Смежные вопросы