awk: объединить строки с уникальным содержимым в каждой строке с одинаковым идентификатором - PullRequest
0 голосов
/ 16 января 2019

У меня есть список записей, каждая из которых разделена разрывом строки, где каждая запись представляет собой набор значений через запятую. Разделение запятыми должно напоминать значения для каждого столбца. Некоторые записи соответствуют одному и тому же идентификатору (первое значение в каждой записи), но имеют разные страны и регионы. (список ниже)

Я пытаюсь сгруппировать записи, которые имеют общий идентификатор, но которые в противном случае могут иметь разные страны и регионы, в одну запись строки, где связанные несколько стран и / или регионов добавляются в соответствующий столбец и отделяются друг от друга последовательность "%%%".

До сих пор мне удалось несколько добиться этого с помощью awk, но побочным эффектом моего подхода является то, что теперь у меня есть дубликаты для столбца регионов.

Таким образом, я не уверен, стоит ли мне продолжать свой текущий подход на основе awk или перейти к более масштабируемому решению, которое справится с работой.

awk -F ',' -v OFS=',' '{x=$1;$1="";ctry[x]=ctry[x]$10"%%% ";$10="";a[x]=$0; str=a[x]; }END{for(x in a){outputString=("\n" x a[x] ctry[x]"\n"); gsub (/%%% \n/,"",outputString); print outputString}}' list.csv > final.csv

Содержимое list.csv:

123123, Shelf Life Test,f,Other,066900,Germany,809900,Chem CMI,066900,Europe
123123, Shelf Life Test,f,Other,066900,Poland,810000,Chem CMI,066900,APAC
123123, Shelf Life Test,f,Other,066900,Spain,810100,Chem CMI,066900,APAC
123123, Shelf Life Test,f,Other,066900,France,2810200,Chem CMI,066900,North America
456456,Ammonium Citrus Esther,f,SupraTex Chem Analysis, 475000, Nigeria,814600,Chem Sensory,129475,MEA (Middle East and Africa)
789789,Archive 9 BASES II,f,HydroCare,066900,Belgium,211500,Chem CMI,066900,CIS (Commonwealth of Independent States)

Токовый выход:

789789,Archive 9 BASES II,f,HydroCare,066900,Belgium,211500,Chem CMI,066900,CIS (Commonwealth of Independent States)

456456,Ammonium Citrus Esther,f,SupraTex Chem Analysis, 475000, Nigeria,814600,Chem Sensory,129475,MEA (Middle East and Africa)

123123, Shelf Life Test,f,Other,066900,France,2810200,Chem CMI,066900,Europe%%% APAC%%% APAC%%% North America

Ожидаемый результат:

789789,Archive 9 BASES II,f,HydroCare,066900,Belgium,211500,Chem CMI,066900,CIS (Commonwealth of Independent States)

456456,Ammonium Citrus Esther,f,SupraTex Chem Analysis, 475000, Nigeria,814600,Chem Sensory,129475,MEA (Middle East and Africa)

123123, Shelf Life Test,f,Other,066900,Germany%%% Poland%%% Spain%%% France,2810200,Chem CMI,066900,Europe%%% APAC%%% North America

Ответы [ 3 ]

0 голосов
/ 17 января 2019

Попробуйте это решение Perl

$ cat ginzburg.txt
123123, Shelf Life Test,f,Other,066900,Germany,809900,Chem CMI,066900,Europe
123123, Shelf Life Test,f,Other,066900,Poland,810000,Chem CMI,066900,APAC
123123, Shelf Life Test,f,Other,066900,Spain,810100,Chem CMI,066900,APAC
123123, Shelf Life Test,f,Other,066900,France,2810200,Chem CMI,066900,North America
456456,Ammonium Citrus Esther,f,SupraTex Chem Analysis, 475000, Nigeria,814600,Chem Sensory,129475,MEA (Middle East and Africa)
789789,Archive 9 BASES II,f,HydroCare,066900,Belgium,211500,Chem CMI,066900,CIS (Commonwealth of Independent States)

$ perl -F, -lanE ' $x=join(",",@F[0..4]);$kv{$x}=join(",",@F[6..8]);@t=@{$kv2{$x}};push(@t,$F[5]);$kv2{$x}=[@t]; @p=@{$kv3{$x}};push(@p,$F[-1]);$kv3{$x}=[@p]; END { for(keys %kv) { %tv=(); %tv=map{$_=>1} @{$kv3{$_}};print "$_ ",join("%%",@{$kv2{$_}})," ",$kv{$_},",",join("%%",keys %tv) } } ' ginzburg.txt
456456,Ammonium Citrus Esther,f,SupraTex Chem Analysis, 475000  Nigeria 814600,Chem Sensory,129475,MEA (Middle East and Africa)
123123, Shelf Life Test,f,Other,066900 Germany%%Poland%%Spain%%France 2810200,Chem CMI,066900,Europe%%North America%%APAC
789789,Archive 9 BASES II,f,HydroCare,066900 Belgium 211500,Chem CMI,066900,CIS (Commonwealth of Independent States)

$
0 голосов
/ 17 января 2019

Пожалуйста, попробуйте что-то вроде:

awk -F, '{
    x=$1;
    if (!shown[x,$10]++)
        ctry[x]=ctry[x]$10"%%% ";
    if (!shown[x,$6]++)
        nation[x]=nation[x]$6"%%% ";
    a[x]=$1","$2","$3","$4","$5
    b[x]=$7","$8","$9
}
END{
    for(x in a){
        gsub (/%%% $/,"",nation[x]);
        gsub (/%%% $/,"",ctry[x]);
        print a[x]","nation[x]","b[x]","ctry[x]"\n";
    }
}' list.csv > final.csv

Вы увидите, что приведенный выше сценарий основан на сценарии ОП с некоторыми изменениями и рефакторингом. Точка - это строка: if (!shown[x,$10]++) и следующая аналогичная, которая позволяет избежать дублирования.

0 голосов
/ 17 января 2019

В одну сторону:

awk -F, '($1 in a){x=a[$1];len=split(x,arr,",");arr[6]=arr[6]"%%% "$6;y=arr[1];arr[10]=arr[10]"%%% "$10;for(i=2;i<=len;i++){y=y","arr[i];a[$1]=y;}next;}{a[$1]=$0;}END{for(i in a){print a[i];}}' file
...