根据另一列从文件中获取一列

根据另一列从文件中获取一列

我有一个包含大约 500 万条记录的文件,如下所示:-

1223423,21,foo,data1,data2,data3,data4,data5,45,267,index1
4234234,34,bar,cat1,cat2,cat3,cat4,cat5,34,2323,index2
325423,23,foo,data1,data2,data3,data4,data5,23,1232,index3
2131,23,bar,cat1,cat2,cat3,cat4,cat5,22,4334,index4
1231,43,cat,val1,val2val3,val4,val5,96,4598,index5
4596,87,cat,val1,val2val3,val4,val5,08,234,index6

期望的输出:

foo,data1,data2,data3,data4,data5 : index1,index3
bar,cat1,cat2,cat3,cat4,cat5 : index2,index4
cat,val1,val2val3,val4,val5 : index5,index6

答案1

如果有效的话试试这个

awk -F, '{a[$3$4$5$6$7$8]++;if(a[$3$4$5$6$7$8] > 1)k[$3$4$5$6$7$8]=k[$3$4$5$6$7$8]","$11;else k[$3$4$5$6$7$8]=$3","$4","$5","$6","$7","$8":"$11}'END'{for(i in k) print k[i]}' data

我在线上有疑问

4596,87,cat,val1,val2val3,val4,val5,08,234,index6

val2val3??之间没有逗号(,)这是正确的吗?

答案2

对于非常大的文件,通常最好对数据进行排序,这样其余的事情就更容易并且不需要任何内存。 sort 旨在处理非常大的数据集。

下面删除不需要的列,对数据进行排序,然后 awk 只需抑制重复的列,而无需记住多行。最后的排序是可选的,以使索引按顺序排列。

cut -d, -f 3-8,11 |
sort |
awk -F, '
{ new = sprintf("%s,%s,%s,%s,%s,%s",$1,$2,$3,$4,$5,$6)
  if(new==last)printf ",%s",$7
  else{ printf "%s%s: %s",newline,new,$7
        last = new
        newline = "\n"
  }
}
END{printf "\n"}
' |
sort -t: -k 2

答案3

您可以awk在读取文件时构建一个数组(在内存中),然后对该数组进行 END 处理以根据需要进行输出。

然而,从记录中删除前 2 个和后 3 个字段后,仍然有许多字段成为数组的键。

awk -F, '{ ix=$NF
           sub( "[^,]+,[^,]+,","")       # delete first 2 fields
           sub(",[^,]+,[^,]+,[^,]+$","") # delete last 3 fields
           a[$0]=a[$0] ","ix }  
      END{ for( r in a ) { sub(",","",a[r]);  print r" : "a[r] }
         }' file

输出:

cat,val1,val2val3,val4,val5 : index5,index6
bar,cat1,cat2,cat3,cat4,cat5 : index2,index4
foo,data1,data2,data3,data4,data5 : index1,index3

相关内容