соединяйте 2 строки, только если field-1 равно sed или awk - PullRequest
0 голосов
/ 20 ноября 2011

входной файл:

$ cat t.txt
id1;value1_1
id1;value1_2
id2;value2_1
id3;value3_1
id4;value4_1
id4;value4_2
id5;value5_1

результат будет:

id1;value1_1;id1;value1_2
id3;value3_1
id4;value4_1;id4;value4_2
id5;value5_1

с использованием sed или awk.Пожалуйста, выскажите свое мнение.

Ответы [ 3 ]

5 голосов
/ 20 ноября 2011

Вот один из способов сделать это:

awk -F';' 'BEGIN { getline; id=$1; line=$0 } { if ($1 != id) { print line; line = $0; } else { line = line ";" $0; } id=$1; } END { print line; }' t.txt

Объяснение:

Установить разделитель полей на ;:

-F';'

Начать с чтения первой строкиввода (getline), сохраните первое поле ($1) как id, а первую строку ($0) как line:

BEGIN { getline; id=$1; line=$0 }

Для каждой строки ввода, проверьте, отличается ли первое поле от сохраненного идентификатора:

if ($1 != id)

Если это так, распечатайте сохраненную строку и сохраните новую ($0):

print line; line = $0;

В противном случае добавьте новую строку к сохраненным строкам:

line = line ";" $0;

и сохраните новый идентификатор:

id=$1

В конце выведите все, что осталось в line:

END { print line; }
1 голос
/ 20 ноября 2011

Это может сработать для вас:

 sed -e '1{h;d};H;${x;:a;s/\(\([^;]*;\)\([^\n]*\)\)\n\2/\1;\2/;ta;p};d' t.txt

Объяснение:

Приблокировать файл для хранения пробела (HS), затем выполнить обмен в конце файла с HS и использовать конкатенацию подстановкилинии с дубликатами ключей и печатью.NB строки, которые обычно печатаются, удаляются.

РЕДАКТИРОВАТЬ:

Приведенное выше решение работает (насколько я знаю), но для больших объемов не очень быстро (читать невероятно медленно).Это решение лучше:

# cat -A /tmp/t.txt 
id1;value1_1$
id1;value1_2$
id2;value2_1$
id3;value3_1$
id4;value4_1$
id4;value4_2$
id5;value5_1$
# for x in {1..1000};do cat /tmp/t.txt;done | 
> sed ':a;$!N;/^\([^;]*;\).*\n\1/s/\n//;ta;P;D'| sort | uniq
id1;value1_1;id1;value1_2
id2;value2_1
id3;value3_1
id4;value4_1;id4;value4_2
id5;value5_1
1 голос
/ 20 ноября 2011

Я думаю, в вашем примере результата, id2; линия отсутствует по ошибке, верно?

в любом случае, вы можете попробовать строку ниже:

awk -F';' '{a[$1]=($1 in a)?a[$1]";"$0:$0}END{for(x in a)print a[x]}' yourFile|sort

вывод будет:

id1;value1_1;id1;value1_2
id2;value2_1
id3;value3_1
id4;value4_1;id4;value4_2
id5;value5_1
...