awk打印每列中唯一值出现的增量计数

时间:2017-09-23 00:23:43

标签: unix awk

要打印以逐步计数,然后打印第1列和第1列中唯一值的计数。第2栏和第2栏第3列......列NF和列$ 0 如果单词只出现在第1列的一次,则希望打印备注为"否"作为重复的标志 如果单词出现在第1列的一次以上,则希望打印备注为"是"作为重复的标志

看起来像这样

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

例如,我试图检查字段$ 1(水果名称)中是否有任何重复信息。 在名称字段下," Apple"出现三次," Orange"出现两次,"芒果"出现一次。 因此,如果任何单词不重复,则会超过一次,因为" Name_Dup = No"重复和计数出现是" Name_Counter = 1" (即芒果)

其中" Apple"出现3次,所以重复/重复 - 标记为"是"当它出现第一次计数是" Name_Dup = Yes"和Name_Counter = 1" , 当它第二次出现" Name_Dup = Yes"和Name_Counter = 2,当它出现第3次" Name_Dup = Yes"和Name_Counter = 3

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

我的实际输入文件未按任何顺序排序。以前的领域没有变化,如10个领域,12个领域和15个领域等

Input.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

步骤#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

2 个答案:

答案 0 :(得分: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

答案 1 :(得分:0)

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