我需要根据.txt
文件分隔的,
文件中的三列来查找重复项。
输入:
a,b,c,d,e,f,gf,h
a,bd,cg,dd,ey,f,g,h
a,b,df,d,e,fd,g,h
a,b,ck,d,eg,f,g,h
让我们来看看基于1,2,5个字段的复制品。
预期产出:
a,b,c,d,e,f,gf,h
a,b,df,d,e,fd,g,h
任何人都可以帮忙为此编写脚本,或者是否有可用的命令?
我试过这样:
awk -F, '!x[$1,$2,$3]++' file.txt but did not work
答案 0 :(得分:2)
使用awk的一种方式:
awk -F, 'FNR==NR { x[$1,$2,$5]++; next } x[$1,$2,$5] > 1' a.txt a.txt
这很简单,但是读取文件两次。在第一遍(FNR == NR),它根据关键字段维护计数。在第二次传递期间,如果多次找到其键,则打印该行。
使用awk的另一种方式:
awk -F, '{if (x[$1$2$5]) { y[$1$2$5]++; print $0; if (y[$1$2$5] == 1) { print x[$1$2$5] } } x[$1$2$5] = $0}' a.txt
说明:
1 awk -F,
2 '{if (x[$1$2$5])
3 { y[$1$2$5]++; print $0;
4 if (y[$1$2$5] == 1)
5 { print x[$1$2$5] }
6 } x[$1$2$5] = $0
7 }'
第2行:如果x有$ 1 $ 2 $ 5,之前看过这个键,请执行步骤3-5
第3行:递增计数并打印该行,因为它是一个重复
第4行:这意味着,我们第二次看到这个键,所以我们需要用这个键打印第一行。上次我们看到这个密钥时,我们不知道它是不是重复。所以我们在第5步打印第一行。
第6行:将当前行存储在键上,以便我们在步骤2中使用它
使用sort,uniq和awk的另一种方法
注意:uniq命令有一个选项' -f'在开始比较之前跳过指定数量的字段。
sort -t,-k1,1 -k2,2 -k5,5 a.txt | awk -F,' BEGIN {OFS =" "} {print $ 0,$ 1,$ 2,$ 5}' | sed' s /,/ / g' | uniq -f7 -D | sed' s / /,/ g' | cut -d',' -f 1-7
这基于字段1,2,5进行排序。 awk打印原始行并附加字段1,2,5。 sed更改分隔符,因为uniq没有指定分隔符的选项。 uniq跳过前7个字段并在其余部分工作并打印重复的行。
答案 1 :(得分:0)
我有类似的问题 我需要消除重复的详细记录,同时保留平面文件记录格式和记录的顺序。 仅由详细信息的第2列中的日期字段的时间扩展引起的重复。 接收系统报告了第4栏和第5栏的重复。
我拼凑了这个快速黑客来解决它。
首先将文件数据读入数组 然后我们可以读取和操作单个记录(粗略地用计数器),如此片段中所示,它集成了一个case语句,用于逻辑处理各种记录类型。
干杯!
readarray inrecs< [输入文件名]
filebase = echo "[input file name] | cut -d '.' -f1
I = 1
for inrec in“$ {inrecs [@]}”;做
FIELD1 = echo ${inrecs[$i-1]} | cut -d',' -f1
FIELD2 = echo ${inrecs[$i-1]} | cut -d',' -f2
字段3 = echo ${inrecs[$i-1]} | cut -d',' -f3
field4中= echo ${inrecs[$i-1]} | cut -d',' -f4
字段5 = echo ${inrecs[$i-1]} | cut -d',' -f5
字段6 = echo ${inrecs[$i-1]} | cut -d',' -f6
字段7 = echo ${inrecs[$i-1]} | cut -d',' -f7
字段8 = echo ${inrecs[$i-1]} | cut -d',' -f8
案件$ field1 in
'H')
echo "$field1,$field2,$field3">${filebase}.new
;;
'D')
dupecount=0
dupecount=`zegrep -c -e "${field4},${field5}" ${infile}`
if [[ "$dupecount" -gt 1 ]];then
writtencount=0
writtencount=`zegrep -c -e "${field4},${field5}" ${filebase}.new`
if [[ "${writtencount}" -eq 0 ]];then
echo "$field1,$field2,$field3,$field4,$field5,$field6,$field7,$field8,">>${filebase}.new
fi
else
echo "$field1,$field2,$field3,$field4,$field5,$field6,$field7,$field8,">>${filebase}.new
fi
;;
'T')
dcount=`zegrep -c '^D' ${filebase}.new`
echo "$field1,$field2,$dcount,$field4">>${filebase}.new
;;
ESAC
(第(i ++))
完成