2014-02-06 2 views
1

В моем сценарии bash я пытаюсь создать два параллельных массива с элементами в файле csv. Файл csv может содержать от 5 до 40 строк.awk, выводящие элементы не по порядку

Array1=($(awk -F, '{a[$1];}END{for (i in a)print i;}' list.csv)) 
Array2=($(awk -F, '{b[$2];}END{for (i in b)print i;}' list.csv)) 

После этого, однако, порядок элементов в массивах не соответствует файлу, и они даже не соответствуют друг другу. Это похоже на то, что awk получает строки случайным образом. Почему это происходит, и как я могу это исправить? Благодаря!

ответ

1
Array1=($(awk -F, 'BEGIN{i=0;}{a[i++]=$1;}END{for(x=0;x<i;x++) print a[x];}' list.csv)) 
Array2=($(awk -F, 'BEGIN{i=0;}{b[i++]=$2;}END{for(x=0;x<i;x++) print b[x];}' list.csv)) 

В AWK у вас есть ассоциативные массивы, поэтому, когда вы выполняете для в этом не уверен, что вы будете получать значения в том же порядке, в котором вы поместили их внутрь. Если вы хотите, чтобы они были заказаны, используйте счетчик как индекс и нормальный цикл, а не для for.

2

Атрибуты ассоциативных массивов не поддерживаются в порядке. Вы видите эффекты внутренней индексации awk.

Вместо этого, вы можете добавить их в нужном порядке, а затем распечатать их в таком порядке:

Array1=($(awk -F, '!a[$1]++ { b[n++]=$1; } END{for (i=0; i<n; i++) print b[i];}' list.csv)) 

Однако, вам даже не нужно хранить их все. Если вы просто хотите, чтобы первый из каждого дубликата:

Array1=($(awk -F, '!a[$1]++ { print $1; }' list.csv)) 

!a[$1]++ является обычным трюком, который правда в первый раз вы видите переменную (a[$1] считается 0, когда не установлено ++ приращений на следующий раз..).

1

Вам, безусловно, не нужно awk для этой задачи: вам не нужно дважды читать файл:

array1=() 
array2=() 
while IFS=, read -r a b; do 
    array1+=("$a") 
    array2+=("$b") 
done < list.csv 
Смежные вопросы