繁体   English   中英

awk:基于另一个常见字段枚举字段

[英]awk: enumerate fields based on another common field

这很可能是用 arrays 完成的,但我不知道如何构建逻辑。

输入:

uid1 ip1 tag1
uid1 ip1 tag2
uid2 ip2 tag3
uid2 ip2 tag4
uid2 ip2 tag5

所需的 output:

uid1 ip1 tag1,tag2
uid2 ip2 tag3,tag4,tag5

我在想,也许这可以通过将所有元素存储在array1中来实现,然后在array2中存储uid + ip字段,然后通过从array2中迭代元素来搜索array1

awk -v OFS=, '{
         k=$1 SUBSEP $2; 
         arr[k] = k in arr ? arr[k] OFS $3 : $0;
      }
      END{
         for(i in arr)
            print arr[i]
      }' infile

试验结果:

$ cat f1
uid1 ip1 tag1
uid1 ip1 tag2
uid2 ip2 tag3
uid2 ip2 tag4
uid2 ip2 tag5

$ awk -v OFS=, '{k=$1 SUBSEP $2; arr[k] = k in arr ? arr[k] OFS $3 : $0;}END{for(i in arr)print arr[i]}' f1
uid1 ip1 tag1,tag2
uid2 ip2 tag3,tag4,tag5

解释:

awk -v OFS=, '{                                   # output field separator
         # variable k contains field1 value 
         # and  SUBSEP - Multi-dimensional array separator 
         # and column 2 value

         k=$1 SUBSEP $2; 

         # arr -> array
         # if array key that is variable k already exists in array arr
         # then arr[k] will be existing content of arr[k]  plus
         # field separator (comma) and then field 3 contents
         # else entire row/record which is when array does not have index already

         arr[k] = k in arr ? arr[k] OFS $3 : $0;

      }
      END{                      # END block

         # iterate through array arr
         # and print array value

         for(i in arr)
            print arr[i]

      }' infile

下面的三元运算符

arr[k] = k in arr ? arr[k] OFS $3 : $0;

if(k in arr){
  arr[k] = arr[k] OFS $3
}else{
  arr[k] = $0
}

使用GNU 数据集

$ datamash -W -t' ' -g1,2 collapse 3 <ip.txt
uid1 ip1 tag1,tag2
uid2 ip2 tag3,tag4,tag5
  • -W使用空格/制表符作为输入字段分隔符
  • -t' '空格作为 output 字段分隔符
  • -g1,2基于字段12的组
  • 对字段3执行的collapse 3操作

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM