打印与某个字段相关的所有数据

打印与某个字段相关的所有数据

考虑以下文件:

foo,5
foo,7
foo,9
boo,5
boo,10
boo,10

我想要的是将与一条记录$2相关的所有数据打印出来。$1

对于此示例,所需的输出将是:

foo,5,7,9
boo,5,10

答案1

解决方案awk

awk 'BEGIN{OFS=FS=","}!(($1,$2)in c){c[$1,$2]=1;r[$1]=r[$1] OFS $2}
            END{for(i in r){print i r[i]}}' file
  1. 设置OFS=FS为一致性。
  2. 使用awk多维数组记住$2到目前为止遇到的值。仅当没有匹配项时才“继续”( !(($1,$2)in c))。
  3. 在第一次遇到新键时为多维数组提供一个“虚拟”值。
  4. 为了方便起见,将所需的输出字符串连接到另一个数组中。
  5. 在 处END,打印循环。
    • 请注意,循环迭代没有任何特定的顺序,awk如果需要,您可以使用 的排序功能。

答案2

将数据解析为“哈希”或“关联数组”或“字典”或任何名称:

perl -F, -lane '$first{$F[0]}->{$F[1]} = (); END { print join(",", $_, sort { $a <=> $b } keys %{ $first{$_} } ) for keys %first }' < inputfile

答案3

bash 中没有 awk 的解决方案:

$ cat bla.txt 
foo,5
foo,7
foo,9
boo,5
boo,10
boo,10

$ { buffer="";
  while read i ; do
    key="${i%,*}" ;
    if [[ "$key" == "$oldkey" ]] ; then
      idx="${i#*,}";
      if [[ ! "$idx" == "$oidx" ]] ; then
        buffer+=",$idx" ;
        oidx="$idx";
      fi ;
    else
      test -z $buffer || echo $buffer ;
      oldkey="$key" ;
      buffer="$i" ;
      oidx="${i#*,}" ;
    fi ;
  done ; echo $buffer ; } < bla.txt
foo,5,7,9
boo,5,10
$

它不漂亮也不短,但是很有效。我也有兴趣看到 awk 的解决方案。

答案4

gnu datamash:

datamash -t ',' -s -g 1 unique 2 <infile

输出中的值的顺序会有所不同,因为它们在处理之前已排序:

boo,10,5
foo,5,7,9

相关内容