使用sed删除括号内的重复数字
我正在尝试使用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”未被删除,因为它没有重复。我不知
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)
>