Unix: объединить несколько столбцов с несколькими значениями на основе общего столбца? - PullRequest
1 голос
/ 20 октября 2019

Итак, у меня есть два файла с разделителями табуляции с двумя столбцами, которые мне нужно объединить на основе значений в общем столбце. Проблема в том, что некоторые значения в общем столбце повторяются с различными значениями во 2-м столбце ... Например:

File 1:  
A 3456  
B 234  
A 4509  
A 576  
C 122  
B 235  


File 2:  
A 48556  
A 49  
B 9694  
C 84  
C 96  

Desired Output:  
A 3456 4509 576 48556 49  
B 234 235 9694  
C 122 84 96  

Я пытаюсь создать «простой» сценарий в Unix, который мог бы сделать это, ичестно говоря, даже не знаю с чего начать.

Ответы [ 3 ]

1 голос
/ 21 октября 2019

К вашему сведению, ваш вопрос немного вводит в заблуждение. Вы не хотите объединяться в общем столбце. Вы хотите перечислить все отдельные значения в N файлах с общим ключом. В терминах SQL это больше похоже на то, что иногда называют «сворачиванием».

Вот один из способов сделать это, близкий к указанному вами выводу:

$ sort -u -k1  d1 d2 | 
  awk '$1 != prev { if (line) {print line}; prev = $1; line = $0; next;} 
       {line = line " " $2} 
       END{ print line }' 
A 3456 4509 48556 49 576
B 234 235 9694
C 122 84 96
1 голос
/ 20 октября 2019

Вот подход awk , объединяющий два файла: -

awk '
        {
                I[$1]
                A[$1 FS $2]
        }
        END {
                for ( k in I )
                {
                        printf "%s ", k
                        for ( j in A )
                        {
                                split( j, T )
                                if ( T[1] == k )
                                        printf "%d ", T[2]
                        }
                        printf "\n"
                }
        }
' file1 file2
0 голосов
/ 21 октября 2019

Другой awk:

$ awk '{a[$1]=a[$1] OFS $2}END{for(i in a)print i a[i]}' file1 file2 #...

Вывод в порядке по умолчанию awk:

A 3456 4509 576 48556 49
B 234 235 9694
C 122 84 96

Объяснено:

$ awk '{
    a[$1]=a[$1] OFS $2   # group by 1st field value by hashing to an array, 
}                        # append 2nd field values to it
END {                    # after processing the data records
    for(i in a)          # iterate all array elements 
        print i a[i]     # print key and value
}' file1 file2           # all the files you want to process
...