2017-09-23 80 views
0

希望打印以递增计数,然后打印第1列中的唯一值的计数第2列&第3列...列NF和列$ 0 和如果单词仅出现在第1列的一次,则想要将备注打印为“否”作为重复标记 ,并且如果该单词出现多于第1列的一次,则打算将重复打印为“是”的备注标志awk打印每列中唯一值出现的增量计数

看起来像这样

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

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

其中“Apple”出现3次,所以它是当出现第一次计数时,重复/重复的标记为“是”,其为“Name_Dup =是”且Name_Counter = 1“, 当它第二次出现时”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场$ 0检查,$ 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 
+0

一点也不清楚,能否请您添加关于您的预期输出的更多解释,因为在Input_file中,即使他们的计数超过1,字段也很少有NO。 – RavinderSingh13

+0

RavinderSingh13,我已经添加了步骤#1到步骤#4,请检查并让我们知道您是否需要任何其他详细信息 – VNA

+0

对不起,说但不清楚,我们可以有条件,当你需要的时候,当你需要1等等请等这里呢? – RavinderSingh13

回答

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 
+0

Marc Lambrichs,哇,优秀的代码,感谢大家的支持,并投票赞成! – VNA

0

你不提供你放在什么样的努力至今。这里有一个提示,我会开始。我想,因为awk是使用的工具,所以从shell命令开始排序Input.csv并将其传递给awk。在读取输入时填充数组,以及索引第一个字段的关联数组。 END END部分遍历数组,查看是否多次找到第一个字段。这需要一点时间,但这听起来像一个家庭作业。不是生产问题。

+0

恕我直言,这将是更适合评论部分,而不是一个答案。 – RavinderSingh13

+0

Krassi Em,在实时情况下,我们正在从我们的供应商那里得到诸如国家明智,区域明智,产品明智,产品代码明智,费率信息和AZ目的地的报价 因此,在国家一级,区域一级,产品水平等等,因此我们无法决定哪些重复行需要删除,发布上述人口的期望输出,我们可以检查并迅速做出决定。 – VNA