gabungkan beberapa baris berdasarkan kolom1

8

Saya punya file seperti di bawah ini ..

abc, 12345
def, text and nos    
ghi, something else   
jkl, words and numbers

abc, 56345   
def, text and nos   
ghi, something else 
jkl, words and numbers

abc, 15475  
def, text and nos 
ghi, something else
jkl, words and numbers

abc, 123345
def, text and nos
ghi, something else  
jkl, words and numbers

Saya ingin mengonversinya (bergabung) sebagai:

abc, 12345, 56345, 15475, 123345
def, text and nos, text and nos,text and nos,text and nos
ghi, something else, something else, something else, something else   
jkl, words and numbers, words and numbers, words and numbers, words and numbers
pvkbhat
sumber
2
Apakah Anda benar-benar memiliki baris kosong tambahan di file input Anda? Jika tidak, harap edit dan hapus, Anda harus menunjukkan file persis seperti apa adanya.
terdon

Jawaban:

10

Jika Anda tidak keberatan dengan urutan output:

$ awk -F',' 'NF>1{a[$1] = a[$1]","$2};END{for(i in a)print i""a[i]}' file 
jkl, words and numbers, words and numbers, words and numbers, words and numbers
abc, 12345, 56345, 15475, 123345
ghi, something else, something else, something else, something else
def, text and nos, text and nos, text and nos, text and nos

Penjelasan

  • NF>1 artinya kita hanya perlu memproses untuk baris yang tidak kosong.
  • Kami menyimpan semua bidang pertama dalam array asosiatif a, dengan kuncinya adalah bidang pertama, nilainya adalah bidang kedua (atau sisa baris). Jika kunci sudah memiliki nilai, kami menggabungkan dua nilai.
  • Dalam ENDblok, kita loop melalui array asosiatif a, mencetak semua kuncinya dengan nilai yang sesuai.

Atau menggunakan perlakan menjaga urutan:

$perl -F',' -anle 'next if /^$/;$h{$F[0]} = $h{$F[0]}.", ".$F[1];
    END{print $_,$h{$_},"\n" for sort keys %h}' file
abc, 12345, 56345, 15475, 123345

def, text and nos, text and nos, text and nos, text and nos

ghi, something else, something else, something else, something else

jkl, words and numbers, words and numbers, words and numbers, words and numbers
cuonglm
sumber
solusi perl Anda dari pertanyaan saya unix.stackexchange.com/questions/124181/… juga harus bekerja dengan benar?
Ramesh
Tidak. OP ingin membuat string berdasarkan kolom 1, terlepas dari digandakan atau tidak. Pertanyaan Anda tidak ingin digandakan.
cuonglm
Oh oke. Pada pandangan pertama, sepertinya hampir mirip dengan pertanyaan saya. :)
Ramesh
1
Rapi, +1! Itu tidak menjaga urutan, itu hanya membuatnya kembali dalam contoh khusus ini di mana bidang berada dalam urutan abjad.
terdon
Hanya untuk tertawa, saya menulis pendekatan yang hampir sama persis sebelum membaca jawaban Anda: perl -F, -lane 'next unless /./;push @{$k{$F[0]}}, ",@F[1..$#F]"; END{print "$_@{$k{$_}}" foreach keys(%k)}' file:) Pemikir hebat sama saja!
terdon
1

Oh, itu mudah. Berikut ini adalah versi sederhana yang menjaga urutan kunci ketika muncul di file:

$ awk -F, '
    /.+/{
        if (!($1 in Val)) { Key[++i] = $1; }
        Val[$1] = Val[$1] "," $2; 
    }
    END{
        for (j = 1; j <= i; j++) {
            printf("%s %s\n%s", Key[j], Val[Key[j]], (j == i) ? "" : "\n");       
        }                                    
    }' file.txt

Output akan terlihat seperti ini:

abc, 12345, 56345, 15475, 123345

def, text and nos, text and nos, text and nos, text and nos

ghi, something else, something else, something else, something else

jkl, words and numbers, words and numbers, words and numbers, words and numbers

Jika Anda tidak keberatan memiliki baris kosong tambahan di bagian akhir, cukup ganti printfbaris denganprintf("%s %s\n\n", Key[j], Val[Key[j]]);


sumber