如何为列表项生成唯一编号

时间:2015-01-16 14:57:51

标签: bash shell awk sed

我在一个名为list.txt的文件中有一长串值,我想为文件文本文件中的每个项目生成一个随机唯一编号。如果该项目出现多次,则它将具有相同的唯一ID

例如list.txt将是:

may-111
may-111
rob-222
kim-456
may-111

我希望能够为每个项目分配一个随机数。如果该项目出现多次,则它将具有相同的唯一ID号,因此预期输出应为: -

may-111 - 789
may-111 - 789
rob-222 - 365
kim-456 - 641
may-111 - 789

我已尝试生成随机数列表并保存到新文本文件,然后将pastejoin新文本文件保存到list.txt

paste -d list.txt random.txt

目前,输出不保留唯一ID,如果同一名称出现多次,则其ID不同。

2 个答案:

答案 0 :(得分:3)

您可以创建一个标识符,该标识符是第一次出现的行号:

$ awk '{if ($1 in a) {c=a[$1]} else {c=NR; a[$1]=c}} {print $1, c}' file
may-111 1
may-111 1
rob-222 3
kim-456 4
may-111 1

这样,你就不会得到任何重复的值。

更惯用(thanks to JID's suggestion):

awk '{!a[$0]&&a[$0]=NR}{print $0,a[$0]}' file

解释

这将id存储在数组a[]中,这样每次我们读取一行时,我们都会检查它是否已经定义了相关的值。

  • {if (...) {action if true} else {action if false}
  • {if ($1 in a) {c=a[$1]} else {c=NR; a[$1]=c}}从我们第一次读取该行时获取相关值。如果不是这种情况,请获取存储的值。
  • print $1, c将内容与标识符一起打印。

你当然可以调整它:

  • 对于其他输出分隔符,请使用-v OFS=" - ",例如。
  • 对于更大的关联值,求和或乘以或等于常数。

答案 1 :(得分:2)

你可以使用这个awk:

awk '!seen[$1]{seen[$1] = rand() * 1000000} {print $0 " - " seen[$1]}' file
may-111 - 840188
may-111 - 840188
rob-222 - 394383
kim-456 - 783099
may-111 - 840188
  • rand()是生成0.840188
  • 等随机数的函数
  • seen是一个关联数组,键为$1,值为随机数
  • !seen[$1] - 对不在数组seen
  • 中的键执行此块
  • seen[$1] = rand() * 1000000 - 使用key=$1value=rand()
  • 填充数组
  • {print $0 " - " seen[$1]} - 从数组中打印当前行和密钥$1的随机值。

编辑:(感谢JID)可以使用此awk命令来避免重复数字:

awk '!seen[$0]{do{x=int(rand()*1000);seen[$0]=x}while(nums[x])} 
     {print $0, "-", seen[$0]}' ile
may-111 - 840
may-111 - 840
rob-222 - 394
kim-456 - 783
may-111 - 840