Awk 过滤重复或三次重复的行++;通过匹配键和筛选列

Awk 过滤重复或三次重复的行++;通过匹配键和筛选列,awk,filter,duplicates,screen,Awk,Filter,Duplicates,Screen,我被重复/三次过滤的复杂性所困扰。解决方案最好是awk,但也可以是sort-u或unique等 我想在前三列中过滤具有唯一或精确重复/三次重复等值的行。应打印整行,包括第四列,其中不应与任何内容匹配。考虑这个选项卡分离表: 编辑:$2和$3值不必在一行内进行比较。根据建议,我将$3的值更改为2xx name value1 value2 anyval a 1 21 first b 2 22 second b 2 22 third c 3 23 fourth c 3 28 fifth d 4 24

我被重复/三次过滤的复杂性所困扰。解决方案最好是awk,但也可以是sort-u或unique等

我想在前三列中过滤具有唯一或精确重复/三次重复等值的行。应打印整行,包括第四列,其中不应与任何内容匹配。考虑这个选项卡分离表:

编辑:$2和$3值不必在一行内进行比较。根据建议,我将$3的值更改为2xx

name value1 value2 anyval
a 1 21 first
b 2 22 second
b 2 22 third
c 3 23 fourth
c 3 28 fifth
d 4 24 sixth
d 4 24 seventh
e 4 25 eighth
e 4 25 ninth
f 7 27 tenth
f 7 27 eleventh
f 7 27 twelveth
f 7 27 thirteenth
g 11 210 fourteenth
g 10 210 fifteenth
第1行是唯一的,应该打印。 第2+3行包含完全重复的值,应打印其中一个。 第4+5行在第3列中包含不同的值,应将其踢出。 第6+7行是重复的,但它们应该被踢出,因为第8+9行在第2列中包含相同的值。 第8+9行也是如此。 应打印第10至13行中的一行

期望输出:

a 1 21 first
b 2 22 second
f 7 27 tenth
。。。或b和f中的任何一个


到目前为止,我所得到但失败的:

awk '!seen[$1]++ && !seen[$2]'
根据列1打印所有重复行

a   1   21  first
b   2   22  second
c   3   23  fourth
d   4   24  sixth
e   4   25  eighth
f   7   27  tenth

印刷品

a   1   21  first
b   2   22  second
c   3   23  fourth
d   4   24  sixth
f   7   27  tenth

因此,如果出现以下情况,awk应打印所需结果:

awk '!seen[$1]++ && !seen[$2]++ && !seen[$3]++'
但是输出是空的


另一种尝试:在第1列中打印重复,然后在第2列和第3列中再次执行相同的步骤-不起作用,因为第2列中有重复

awk -F'\t' '{print $1}' file.txt |sort|uniq -d|grep -F -f - file.txt
首先打印第1列中没有“a”的副本,我可以稍后进行cat

b   2   22  second
b   2   22  third
c   3   23  fourth
c   3   22  fifth
d   4   24  sixth
d   4   24  seventh
e   4   25  eighth
e   4   25  nineth
f   7   27  tenth
f   7   27  eleventh
f   7   27  twelveth
f   7   27  thirteenth
但是,我再次陷入了跨越多个列的重复值(例如4)中



我认为解决方案可能是定义col1单集和多集,并在所有其他列中筛选重复值,但这会在我的大脑中造成大量堆栈溢出。

我不是100%清楚这些要求,但你可以分阶段筛选记录

$ awk '!a[$1,$2,$3]++{print $0,$2}' file | 
  uniq -uf4 | 
  cut -d' ' -f1-4

a 1 1 first
b 2 2 second
f 7 7 tenth
第一个
awk
根据前三个字段过滤所有重复条目,并打印第二个字段供下一个流程使用,唯一的过滤器仅基于第二个字段(现在位于第四位置)并删除所有副本,剪切删除多余的关键字段

更新

要过滤唯一的$2和$3字段,我们必须返回到
awk

$ awk '!a[$1,$2,$3]++ {f2[$2]++; f3[$3]++; line[$2,$3]=$0} 
       END            {for(i in f2) 
                         for(j in f3) 
                           if((i,j) in line && f2[i]*f3[j]==1) print line[i,j]}' file | 
  sort

a 1 1 first
b 2 2 second
f 7 7 tenth

既然你在读第8行和第9行时丢弃了第6行和第7行,我想你必须将数据存储在一个数组中,并在遍历整个文件后打印它的所有元素。保持
b2秒
但失去
c3第四
有什么意义,因为在
c3第五
3=2?我不够精确:只应分析前三列,不应考虑第四列,并且包含任何将要打印的值。@詹姆斯·布朗:逻辑故障,更正了C3 2到C3 8。2美元和3美元的值是否相互比较?如果没有,可能会将示例输入的$3值更改为不同于$2值。问题是这没有考虑第三列。我在表格上又加了两行,以说明我的意思。
$ awk '!a[$1,$2,$3]++ {f2[$2]++; f3[$3]++; line[$2,$3]=$0} 
       END            {for(i in f2) 
                         for(j in f3) 
                           if((i,j) in line && f2[i]*f3[j]==1) print line[i,j]}' file | 
  sort

a 1 1 first
b 2 2 second
f 7 7 tenth