【问题标题】:awk: Merge rows with unique content to each row of same idawk:将具有唯一内容的行合并到具有相同 id 的每一行
【发布时间】:2019-06-11 00:13:04
【问题描述】:

我有一个条目列表,每个条目由一个换行符分隔,其中每个条目是一组以逗号分隔的值。逗号分隔用于类似于每列的值。一些条目映射到相同的 id(每个条目中的第一个值)但具有不同的国家和地区。 (下面列出)

我正在尝试将共享相同 ID 但可能具有不同国家和地区的条目分组到单个行条目,其中关联的多个国家和/或地区附加到相应的列并通过'%%%' 序列。

到目前为止,我已经设法通过 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

【问题讨论】:

  • 为什么只有法国被认为是 id 123123?
  • @stack0114106,更正了输出。它当然应该包含所有相应的国家,而不仅仅是法国。
  • 您的脚本没有生成 uodated Current output。另外我想知道为什么更新的Expected output中缺少Latin AmericaMEA (Middle East and Africa)CIS (Commonwealth of Independent States) ...等。它们确实存在于原始帖子中。请说明您想如何处理第 6 个字段(国家名称)和第 10 个字段(地区名称)?
  • @tshiono,我试图提供一个问题的最小示例,所以我删除了一些条目以使问题更清楚。国家名称和地区名称应分组到各自的列中,唯一并用'%%%'分隔。
  • 对不起,我忽略了你也更新了list.csv。现在我已经了解您想要什么并相应地发布了答案。

标签: arrays string bash awk gsub


【解决方案1】:

请尝试以下方法:

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

您会看到上面的脚本基于 OP 的脚本,并进行了一些重构和修改。重点是行:if (!shown[x,$10]++) 和以下类似的行,以避免重复。

【讨论】:

    【解决方案2】:

    一种方式:

    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
    

    【讨论】:

    • 这确实解决了国家和地区列的问题。但是,它仍然会导致重复的(国家和)地区值,例如亚太地区。
    【解决方案3】:

    试试这个 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)
    
    $
    

    【讨论】:

      猜你喜欢
      • 2019-08-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-11-03
      • 2017-10-19
      • 1970-01-01
      • 2012-11-04
      • 2013-05-24
      相关资源
      最近更新 更多