以下 sed 代码段将删除字符串中的重复字母,并仅打印唯一的字母:
> echo "remove duplicate letters from string" | sed ':;s/\(.\)\(.*\)\1/\1\2/;t'
> remov duplicatsfng
只打印重复字母的正则表达式是什么 - 因此丢弃了唯一的字母(例如:v和d),并且不应在输出中重复出现多次出现的字母!
结果应为:
> remo lits
答案 0 :(得分:4)
您可以尝试使用GNU sed:
sed -E ':a;s/(.)\1*(.+)\1+/\1\1\2/;ta;s/(((.)\3)*)./\1/g;s/.(.)/\1/g;'
详细信息:用于字符串"remove duplicate letters from string"
:a;s/(.)\1*(.+)\1+/\1\1\2/;ta;
:此部分用两个连续的字母替换每个由至少一个字符分隔的重复字母。结果:
rreemmoov duplliicattssfng
s/(((.)\3)*)./\1/g;
这个删除了一个人留下的字母。结果:
rreemmoo lliittss
s/.(.)/\1/g
这个删除了连续的字母。结果:
remo lits
使用perl:
你可以用或多或少类似的方式写下这样的东西:
perl -pe's/(.)(?!.*\1)//g;while(s/(.)(.*)\1+/\1\2/g){}'
它更短但是使用第二个版本和autosplit开关并使用哈希来计算每个字符的出现次数可能更有效:
perl -F -ane'$h{$_}++ for(@F);for(@F){if($h{$_}>1){$h{$_}=1;print}}'
答案 1 :(得分:1)
这适用于任何系统上的任何awk:
$ echo "remove duplicate letters from string" |
awk '{ for (i=1;i<=length($0);) { chr=substr($0,i,1); if (gsub(chr,"") > 1) printf "%c", chr } print "" }'
remo lits
答案 2 :(得分:1)
使用posix sed(和gnu)
echo "remove duplicate letters from string" | sed -e ':a' -e 's/\(\(.\).*\2.*\)\2/\1/;ta' -e "G;:b" -e '/^\(.\)\(.*\)\1\(.*\n.*\)/s//\1\2\3\1/;tb' -e 's/.//;/^\n/b e' -e 'b b' -e ':e' -e 's/.//'
概念
':a' -e 's/\(\(.\).*\2.*\)\2/\1/;ta'
G
测试第一个char是否存在两次(在第二行之前),如果是,则将其放在第二行并删除第二次出现的字母:b" -e '/^\(.\)\(.*\)\1\(.*\n.*\)/s//\1\2\3\1/;tb
删除第一个字符s/.//
/^\n/b e'
... -e ':e'
-e 'b b'
答案 3 :(得分:0)
这可能适合你(GNU sed):
sed -r ':a;s/\n*(([^\n]).*)\2/\n\1/;ta;s/\n(.)[^\n]*/\1/g' file
虽然删除重复字符前缀,但使用唯一标记\n
。然后删除与标记无关的所有字符(以及标记),只留下那些具有重复字符的字符。