基于多个字段在unix文本文件中复制

时间:2015-10-21 17:45:53

标签: unix duplicates

我需要根据.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

2 个答案:

答案 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 ++))

完成