Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用sed删除括号内的重复数字_Sed - Fatal编程技术网

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

使用sed删除括号内的重复数字,sed,Sed,我正在尝试使用sed删除括号中的重复数字 因此,我有以下字符串: Abdc 1234 1234 (5678) (5678) (9012) (9012) (3456) 我想使用sed删除括号内的任何4位数字,包括括号。因此,我的字符串应该如下所示: Abdc 1234 1234 (5678) (9012) (3456) 在本例中,删除了“(5678)”和“(9012)”,因为它们是重复出现的括号内的4位数字。“1234”号未删除,因为它们不在括号内。“3456”未被删除,因为它没有重复。我不知

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

因此,我有以下字符串:

Abdc 1234 1234 (5678) (5678) (9012) (9012) (3456)
我想使用sed删除括号内的任何4位数字,包括括号。因此,我的字符串应该如下所示:

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

在本例中,删除了“(5678)”和“(9012)”,因为它们是重复出现的括号内的4位数字。“1234”号未删除,因为它们不在括号内。“3456”未被删除,因为它没有重复。

我不知道如何使用
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 ""
   }'

这将在行字段中循环,然后仅当以前从未见过或不是以
开头时才打印每个字段(

这适用于您的输入:

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'
使用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次出现的带括号的重复内容。

这可能适用于您(GNU-sed):

现在执行:

> 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)
> 

>awk-F“(“{for(a中的i)删除a[i];for(i=2;i你有多行这样的例子吗?有没有重复的组总是紧跟在第一行后面?我不确定任何正则表达式匹配工具是否适合这个工作…没有,只有一行所以没有CR/NL。是的,重复总是连续的。我找到了这个帖子来删除重复的单词。我把它拿到了wo对于重复的数字组,rk很容易:
\echo“Testing 1234 1234 5678”| sed-e's/\b\([0-9]\+\)[,\n]\1/\1/g'
但是,我对regex/sed不太了解,我无法让它与括号中的数字组一起工作。这是个好主意!但是如果重复的条目出现两次以上,这些都不起作用(例如作为输入的
(5678)(5678)(5678)
)。这再次取决于输入格式约束。@jvivenot:我明白了,您可以通过循环
s//
来处理此问题,请参见编辑。
sed ':a;s/\(\(([0-9]\+) *\).*\)\2/\1/g;ta' file
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)
>