使用sed删除括号内的重复数字

时间:2012-11-14 00:17:12

标签: sed

我正在尝试使用sed删除括号内的重复数字。

所以我有以下字符串:

Abdc 1234 1234 (5678) (5678) (9012) (9012) (3456)

我想用sed删除括号内的任何4位数字,包括括号。所以我的字符串应该是这样的:

Abdc 1234 1234 (5678) (9012) (3456)

在这种情况下,“(5678)”和“(9012)”被删除,因为它们是重复括号内的4位数字。 “1234”号码未删除,因为它们不在括号内。 “(3456)”未被删除,因为它没有重复。

5 个答案:

答案 0 :(得分:5)

我不知道如何使用sed执行此操作,但您可以使用awk尝试以下操作:

$  echo "Abdc 1234 1234 (5678) (5678) (9012) (9012) (3456)" | awk '
   {
     for(i=1;i<=NF;i++) { 
       if(substr($i,0,1) != "(" || (seen[$i] != 1)) {
         seen[$i]=1;
         printf "%s ",$i
       }
     };
     print ""
   }'

输出:

Abdc 1234 1234 (5678) (9012) (3456) 

这会遍历行字段,然后仅在以前从未见过或者不是以(开头的情况下打印每个字段。

答案 1 :(得分:2)

这适用于您的输入:

echo 'Abdc 1234 1234 (5678) (5678) (9012) (9012) (3456)' | 
  sed 's/\(([0-9][0-9]*)\) \1/\1/g'

假设重复相互关联,如果不是这样,请使用此版本:

echo 'Abdc 1234 1234 (5678) (5678) (9012) (9012) (3456)' | 
  sed 's/\(([0-9][0-9]*)\) \(.*\)\1/\1\2/g'

或者使用GNU sed扩展表达式更短一些:

echo 'Abdc 1234 1234 (5678) (5678) (9012) (9012) (3456)' | 
  sed -r 's/(\([0-9]+\)) (.*)\1/\1\2/g'

所有情况下的输出:

Abdc 1234 1234 (5678) (9012) (3456)

编辑 - 处理存在两个以上相同项目的情况

这可以通过循环遍历模式直到它不再匹配来完成:

echo 'Abdc 1234 1234 (5678) (5678) (9012) (9012) (3456) (5678) (5678)' | 
  sed -r ':a; s/(\([0-9]+\))(.*)\1 ?/\1\2/g; ta'

答案 2 :(得分:0)

使用Perl:

$ echo "Abdc 1234 1234 (5678) (5678) (9012) (9012) (3456)" |
    perl -ne '
        my (@arr, %hash);
        for (split) {
            if (/^\(.*\)/) {
                $hash{$_}++;
                push @arr, $_ if $hash{$_} == 1;
            }
            else {
                push @arr, $_; 
            }
        }
        print join " ", @arr, "\n";
    '

这将使用多行作为输入和N次出现的带括号的重复内容。

答案 3 :(得分:0)

这可能适合你(GNU sed):

sed ':a;s/\(\(([0-9]\+) *\).*\)\2/\1/g;ta' file

答案 4 :(得分:0)

awk -F"(" '{for(i in a)delete a[i];for(i=2;i<=NF;i++){if($i in a){$i="";}else{a[$i];$i="("$i}}print $0}' your_file

测试如下: 输入:

> cat temp
Abdc 1234 1234 (5678) (5678) (9012) (9012) (3456)
1234 1234 (1234) (5678) (9012) (1234) (3456)
 (5678) (6467) (6467) (9012) (5678)

现在执行:

> awk -F"(" '{for(i in a)delete a[i];for(i=2;i<=NF;i++){if($i in a){$i="";}else{a[$i];$i="("$i}}print $0}' temp
Abdc 1234 1234  (5678)   (9012)   (3456)
1234 1234  (1234)  (5678)  (9012)   (3456)
  (5678)  (6467)   (9012)  (5678)
>