3

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

所以我有以下字符串:

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

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

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

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

4

5 回答 5

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) 

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

于 2012-11-14T00:42:33.610 回答
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'
于 2012-11-14T00:49:24.310 回答
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)
> 
于 2012-11-14T07:21:47.687 回答
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 次出现重复的带括号的内容。

于 2012-11-14T01:10:28.720 回答
0

这可能对您有用(GNU sed):

sed ':a;s/\(\(([0-9]\+) *\).*\)\2/\1/g;ta' file
于 2012-11-14T07:19:01.690 回答