【问题标题】:Identify duplicate records and assign random ids识别重复记录并分配随机 ID
【发布时间】:2018-10-04 14:10:05
【问题描述】:

在一些 unix 的东西上遇到了超级麻烦。这里的任何指导都将不胜感激。

我想根据下面文件中的 id 识别重复记录,并在单独的 col 中为其分配一个唯一的随机数,并将它们的 value 字段相加。 我的输入文件:

name,location,id,state,website,status,color,field1,value,field3,field4,field5
joe,US,23A,CA,g,oog,le,10,blue,0,10,0,0,0
jack,UK,89A,LN,yah,oo,11,red,0,20,0,0,0
joe,US,23A,CA,g,mail,10,blue,0,120,0,0,0
rose,EU,AV45,UN,new,mail,45,black,0,110,0,0,0
Karl,US,2345,NY,microsoft,99,green,0,34,0,0,0
jonas,IN,AW3455,ND,facebook,37,brown,0,48,0,0,0
Karl,US,2345,NY,microsoft,99,purple,0,87,0,0,0
alin,IN,3T45,CA,re,edit,78,white,0,22,0,0,0
alin,IN,3T45,CA,ora,cle,11,orange,0,35,0,0,0

我希望我的输出文件是:

RandonUniqID,ID,Value
2202,23A,130
3029,89A,20
3066,AV45,110
5077,2345,121
1055,AW3455,48
3099,3T45,57

在这里,我想为rec 和那些重复的记录生成唯一的随机ID,我想将它们的值字段汇总在一个单独的字段中。这里最棘手的部分是我的第 5 列 网站 非常动态。该字段中的值将在任何地方放置逗号分隔符。所以这给我带来了麻烦。

【问题讨论】:

  • 要从value 列获取数据而不必担心website 中的嵌入逗号,请使用$(NF - 3)
  • 知道了。但我不确定如何为我的记录生成一个随机数并为此添加值。我尝试了几个 awk 的东西,但是 value 字段中不同的逗号使它全部倾斜
  • Edit 你的问题展示你的尝试。在值字段中使用不同的逗号是什么意思?值字段不是十进制数吗?
  • 不,先生。不在值字段中。我指的是网站领域。很抱歉造成混乱
  • 您还没有添加代码。如果您将迄今为止的工作包括在内,您将获得更多有用的答案。

标签: unix awk sed grep


【解决方案1】:

试试这个:

awk -F ',' '
   NR>1{
      if( ! ( $3 in UID ) ) {

         # select a uniq random id 
         while( (Rnd=int(1000000*rand())) in UID) i++

         UID[$3]=Rnd
         }
      # workaround for 9th col where there are "," inside field
      S[$3]+=$(NF - 3)
      }
    END {
       print "RandonUniqID,ID,Value"
       for( uid in UID ) printf( "%s,%s,%s\n", UID[uid], uid, S[uid])
       }
    ' YourFile

我假设 id 比 1000000 少很多

【讨论】:

  • 感谢您的洞察力。一个问题。我应该如何执行这个?这应该像脚本一样执行还是以命令格式执行
  • 上述程序应该像命令一样执行还是作为脚本使用。当我尝试以 cmd 运行时遇到很多语法错误
  • 这是一个 gawk 命令(在 linux rhel bash 下测试)。我使用文件“YourFile”作为输入。你有哪个错误?
  • awk:NR>1{if(!($3 in UID)) {while((Rnd=int(1000000*rand())) in UID) i++ UID[$3]=Rnd} S [$3]+=$(NF - 3)}END {print"RandonUniqID,ID,Value"for(uid inUID) printf("%s,%s,%s\n", UID[uid], uid, S [uid])}testfile awk: ^ 语法错误 awk: NR>1{if(!($3 in UID)) {while((Rnd=int(1000000*rand())) in UID) i++ UID[$3]= Rnd} S[$3]+=$(NF - 3)} END {print "RandonUniqID,ID,Value"for(uid inUID) printf("%s,%s,%s\n", UID[uid], uid, S[uid])}testfile awk: ^ 语法错误
  • 我想我搞砸了。
【解决方案2】:

像这样:

awk '# Set the input and output field delimiter and print the headers
     BEGIN{FS=OFS=",";print "RandomID,ID,Value"}
     # iteratively calculate the s(um) per id ($3) on each row
     NR>1{s[$3]+=$(NF-3)}
     # Print the results, indexed by an integer r
     END{for(i in s){print r++,i,s[i]}}' input_file

NF 是字段数,$(NF-3) 是倒数第四个字段。

这将生成像这样的顺序 ID:

RandomID,ID,Value
0,3T45,57
1,2345,121
2,23A,130
3,AV45,110
4,AW3455,48
5,89A,20

如果您需要 4 个字符宽的 ID,您可以使用 printf:

awk 'BEGIN{FS=",";print "RandomID,ID,Value"}
     NR>1{s[$3]+=$(NF-3)}
     END{for(i in s){printf "%04d,%s,%d\n",r++,i,s[i]}}' input_file

输出:

RandomID,ID,Value
0000,3T45,57
0001,2345,121
0002,23A,130
0003,AV45,110
0004,AW3455,48
0005,89A,20

【讨论】:

  • awk命令中的[$3]指的是输出或输入文件的第三列
  • awk 中的字段,如 $3,包含输入字段
猜你喜欢
  • 1970-01-01
  • 2018-12-07
  • 1970-01-01
  • 2013-07-14
  • 1970-01-01
  • 2018-06-06
  • 2020-11-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多