我正在尝试使用sed删除括号内的重复数字。
所以我有以下字符串:
Abdc 1234 1234 (5678) (5678) (9012) (9012) (3456)
我想用sed删除括号内的任何4位数字,包括括号。所以我的字符串应该是这样的:
Abdc 1234 1234 (5678) (9012) (3456)
在这种情况下,“(5678)”和“(9012)”被删除,因为它们是重复括号内的4位数字。 “1234”号码未删除,因为它们不在括号内。 “(3456)”未被删除,因为它没有重复。
答案 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)
>