【问题标题】:awk to print incremental count of occurrences of unique values in each columnawk 打印每列中唯一值出现的增量计数
【发布时间】:2017-09-23 00:23:43
【问题描述】:

希望打印增量计数,然后打印第 1 列和第 2 列和第 3 列中唯一值的计数 ...列 NF 和列 $0 如果单词在第 1 列只出现一次,想将备注打印为“否”作为重复标志 如果该词在第 1 列出现多次,想将备注打印为“是”作为重复标志

看起来像这样

awk -F"," '{OFS=","; if (word == $1) { counter++ } else { counter = 1; word = $1 }; print $0 ",", "Yes/No", counter }'

例如,我正在尝试检查字段 $1 (Fruits Name) 中是否有任何重复信息。 在名称字段下,“Apple”出现 3 次,“Orange”出现 2 次,“Mango”出现 1 次。 因此,如果任何单词的重复次数不超过一次,则视为“Name_Dup=No”重复,出现次数为“Name_Counter=1”(即 Mango)

其中“Apple”出现 3 次,因此重复/重复 - 当第一次出现计数为“Name_Dup=Yes”且 Name_Counter=1”时,将其标记为“Yes”, 当它第二次出现“Name_Dup=Yes”和 Name_Counter=2 时,当它第三次出现“Name_Dup=Yes”和 Name_Counter=3 时

然后需要检查每一列 $2, $3 .. 直到 $NF 和 $0 ..

我的实际输入文件没有按任何顺序排序。过去的字段数不等,如 10 个字段、12 个字段和 15 个字段等

输入.csv

Name,Amount,Dept
Apple,10,eee
Orange,20,csc
Apple,30,mec
Mango,40,sss
Apple,10,eee
Orange,10,csc

期望的输出

Name,Amount,Dept,Name_Dup,Name_Counter,Amount_Dup,Amount_Counter,Dept_Dup,Dept_Counter,EntireLine_Dup,EntireLine_Counter
Apple,10,eee,Yes,1,Yes,1,Yes,1,Yes,1
Orange,20,csc,Yes,1,No,1,Yes,1,No,1
Apple,30,mec,Yes,2,No,1,No,1,No,1
Mango,40,sss,No,1,No,1,No,1,No,1
Apple,10,eee,Yes,3,Yes,2,Yes,2,Yes,2
Orange,10,csc,Yes,2,Yes,3,Yes,2,No,1

例如,请参考以下步骤。

步骤#1 - 字段 $1 检查和输出

Name,Name_Dup,Name_Counter
Apple,Yes,1
Orange,Yes,1
Apple,Yes,2
Mango,No,1
Apple,Yes,3
Orange,Yes,2

步骤#2 - 字段 $2 检查和输出

Amount,Amount_Dup,Amount_Counter
10,Yes,1
20,No,1
30,No,1
40,No,1
10,Yes,2
10,Yes,3

步骤#3 - 字段 $3 检查和输出

Dept,Dept_Dup,Dept_Counter
eee,Yes,1
csc,Yes,1
mec,No,1
sss,No,1
eee,Yes,2
csc,Yes,2

Step#4-Field $0 check,$1 & $2 & $3 和输出的组合

"Name,Amount,Dept",EntireLine_Dup,EntireLine_Counter
"Apple,10,eee",Yes,1
"Orange,20,csc",No,1
"Apple,30,mec",No,1
"Mango,40,sss",No,1
"Apple,10,eee",Yes,2
"Orange,10,csc",No,1

【问题讨论】:

  • 不太清楚,能否请您添加更多关于您的预期输出的解释,因为为什么很少有字段有 NO 甚至它们在 Input_file 中的计数超过 1。
  • RavinderSingh13 ,我已将步骤#1 添加到步骤#4,如果您需要任何其他详细信息,请查看并告知
  • 对不起,但还不清楚,当您需要是时,我们可以有条件吗?当您需要 1 等时,请也在这里?

标签: unix awk


【解决方案1】:

awk解决方案:

据我了解,OP 要求每行、每列显示一个列值是否显示不止一次,并给出该特定列的出现次数。

$ cat tst.awk
BEGIN{ FS=OFS="," }
NR==1{
   header=$0
   n=split("Dup,Counter",h)
   for (i=1; i<=NF; i++)
      for (j=1; j<=n; j++) header=header OFS $i"_"h[j]
   printf("%s,EntireLine_Dup,EntireLine_Counter\n", header)
   next
}
{
   r[++lines]=$0
   for (col=1; col<=NF; col++) v[col][$col]++
   v[col][$0]++
}
END {
   for (l=1; l<=lines; l++){
      n=split(r[l], s)
      res=""
      for (c=1; c<=n; c++)
         res=res OFS output(v,c,s[c])
      res=res OFS output(v,c,r[l])
      print r[l] res
   }
}
function output(arr, col, val){
    return sprintf("%s,%s", (arr[col][val] > 1? "Yes" : "No"), ++count[col][val])
}

有输入:

$ cat input.txt
Name,Amount,Dept,Nonsense
Apple,10,eee,eee
Orange,20,csc,eee
Apple,30,mec,eee
Mango,40,sss,eee
Apple,10,eee,eee
Orange,10,csc,eee

这给出了(我已经手动删除了标题行,因为我无法让它适合代码示例):

$ awk -f tst.awk input.txt
# deleted header line
Apple,10,eee,eee,Yes,1,Yes,1,Yes,1,Yes,1,Yes,1
Orange,20,csc,eee,Yes,1,No,1,Yes,1,Yes,2,No,1
Apple,30,mec,eee,Yes,2,No,1,No,1,Yes,3,No,1
Mango,40,sss,eee,No,1,No,1,No,1,Yes,4,No,1
Apple,10,eee,eee,Yes,3,Yes,2,Yes,2,Yes,5,Yes,2
Orange,10,csc,eee,Yes,2,Yes,3,Yes,2,Yes,6,No,1

【讨论】:

  • Marc Lambrichs,哇,优秀的代码,非常感谢您的大力支持和投票!!!
【解决方案2】:

您没有提供到目前为止所做的努力。这是我要开始的提示。我猜因为 awk 是要使用的工具,所以从 shell 命令 sort Input.csv 开始并将其通过管道传输到 awk。读取输入时填充数组以及索引第一个字段的关联数组。 在 END 部分中,检查数组,看看您是否多次找到第一个字段。这需要一点时间,但这听起来像是一项功课。不是生产问题。

【讨论】:

  • 恕我直言,这将更适合 cmets 部分而不是答案。
  • Krassi Em,在实时场景中,我们从供应商处获取报价,如国家、地区、产品、产品代码、A-Z 目的地的费率和成本信息所以,有重复在国家级别、地区级别、产品级别等,因此我们将无法决定需要删除哪些重复的行,发布上述期望输出的人口,我们可以快速检查并做出一些决定。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-09-05
  • 1970-01-01
  • 2015-01-30
  • 2012-02-21
  • 2011-05-12
相关资源
最近更新 更多