объединить несколько строк на основе column1


8

У меня есть файл, как показано ниже ..

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

Я хочу преобразовать (присоединиться) это как:

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

2
У вас действительно есть лишние пустые строки во входном файле? Если нет, пожалуйста, отредактируйте и удалите их, вы должны показать файл в точности так, как он есть.
Тердон

Ответы:


10

Если вы не возражаете против порядка вывода:

$ 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

объяснение

  • NF>1 это означает, что нам нужно обработать только строку, которая не является пустой.
  • Мы сохраняем все первое поле в ассоциативном массиве a, причем ключом является первое поле, значением является второе поле (или остальная часть строки). Если ключ уже имеет значение, мы объединяем два значения.
  • В ENDблоке мы перебираем ассоциативный массив a, печатаем все его ключи с соответствующим значением.

Или с помощью perlсохранит порядок:

$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

ваше perl решение из моего вопроса unix.stackexchange.com/questions/124181/… также должно работать?
Рамеш

Нет. Оператор хочет объединить строку на основе столбца 1, независимо от того, дублирован или нет. Ваш вопрос не хочет дублироваться.
cuonglm

о хорошо На первый взгляд, это было похоже почти на мой вопрос. :)
Рамеш

1
Аккуратно, +1! Это не держать порядок , хотя, это только воссоздает его в этом конкретном примере , где поля в алфавитном порядке.
Тердон

Просто для смеха, я написал почти такой же подход, прежде чем читать ваш ответ: perl -F, -lane 'next unless /./;push @{$k{$F[0]}}, ",@F[1..$#F]"; END{print "$_@{$k{$_}}" foreach keys(%k)}' file:) Великие умы думают одинаково!
Тердон

1

О, это легко. Вот простая версия, которая сохраняет порядок ключей, как они появляются в файле:

$ 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

Вывод должен выглядеть так:

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

Если вы не возражаете иметь лишнюю пустую строку в конце, просто замените printfстроку наprintf("%s %s\n\n", Key[j], Val[Key[j]]);

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.