如何使用awk脚本删除重复列

时间:2014-11-07 03:54:57

标签: unix awk sed gawk

我有以下

444, 1234, (1234), 3453534, 43534543

我希望输出为

444, (1234), 3453534, 43534543

我知道awk是最好的解决方案。

但我无法提出解决方案

新行可以将唯一列放在任何位置。并且只需要括号中的值。

总而言之,如果重复,我们需要摆脱没有括号的值。

e.g。如果我们将列设为::

(1234) 1234 ----> we want it to be (1234)

非常感谢

2 个答案:

答案 0 :(得分:1)

如果我做出以下假设:

  • 每行只有一个唯一列
  • 除最后一行外,分隔符的位置相同:$

然后这是一个awk可执行文件,用于删除问题中所述的重复项:

#!/usr/bin/awk -f

BEGIN {FS=", "}

match($0, /\([[:alnum:]]*\)/) {
  p=substr($0, RSTART, RLENGTH)   # pattern to match
  gsub(p "(" FS "|$){1}", "")     # remove duplicates from $0
  sub(FS "$", "")                 # clean up trailing delimiters
}

47

或者,当删除每行只有一个唯一列的假设时:

#!/usr/bin/awk -f

BEGIN {FS=", "}

{ 
  for(i=1;i<=NF;i++) {
    if(match($0, "\\(" $i "\\)")) { 
      p=substr($0, RSTART, RLENGTH)   # pattern to match
      gsub(p "(" FS "|$){1}", "")     # remove duplicates from $0
    }
  }
  sub(FS "$", "")                     # clean up trailing delimiters
}

47

在每种情况下,使用$0更新gsub以删除重复项而不是对各个字段进行操作,47评估为true以打印$0是否为改变与否。

答案 1 :(得分:0)

如果我对每个输入行都很了解,则必须解析所有(value)字段,然后必须跳过所有value字段。我假设除了最后一个字段外,所有字段都以逗号字符结尾。

这是我的建议:

awk ' { delete a; s="" # Reset tmp values
  #Search for all (...) fields
  for(i=1;i<=NF;++i) {
    if (match($i,/^\((.*)\),?$/)) {
        num=$i; gsub(/(^\(|\),?$)/,"",num);
        a[num","]=1;
    }
  }
  #Skip all fields contained by a hash
  for(i=1;i<=NF;++i) if(!(($i)(i<NF?"":",") in a)) s=s FS $i;
  # Trim leading field separator and trailing comma (if exists)
  gsub("(^"FS"|,$)","",s);
  print s;
}' inputfile

输入文件:

444, 1234, (1234), 3453534, 43534543
444, (1235), 1235, 1235, 1234, 3453534, 43534543
444, (1235), 1235, 1235, 1234, 3453534, 43534543, (1234)
444, 1235, 1235, 1235, 1234, 3453534, 43534543
444, 1234, (1234)
444, (1235), 1235

输出:

444, (1234), 3453534, 43534543
444, (1235), 1234, 3453534, 43534543
444, (1235), 3453534, 43534543, (1234)
444, 1235, 1235, 1235, 1234, 3453534, 43534543
444, (1234)
444, (1235)

我希望这有点帮助!

相关问题