以下sed代码段将删除字符串中的重复字母并仅打印唯一的字母:
> echo "remove duplicate letters from string" | sed ':;s/(.)(.*)1/12/;t'
> remov duplicatsfng
只打印重复字母的正则表达式是什么 - 因此唯一的字母被丢弃(例如:v和d),并且多次出现的字母不应该在输出中重复!
结果应为:
> remo lits
你可以尝试用GNU sed来做到这一点:
sed -E ':a;s/(.)1*(.+)1+/112/;ta;s/(((.)3)*)./1/g;s/.(.)/1/g;'
详细信息:对于字符串"remove duplicate letters from string"
:a;s/(.)1*(.+)1+/112/;ta;
:此部分将每个重复的字母替换为两个连续的字母,这些字母至少由一个字符分隔。结果:
rreemmoov duplliicattssfng
s/(((.)3)*)./1/g;
这个删除了单独存在的字母。结果:
rreemmoo lliittss
s/.(.)/1/g
这个删除了连续的字母。结果:
remo lits
使用 perl:
以或多或少相似的方式,您可以编写如下内容:
perl -pe's/(.)(?!.*1)//g;while(s/(.)(.*)1+/12/g){}'
它更短,但将第二个版本与自动拆分开关和哈希一起使用可能会更有效,以计算每个字符的出现次数:
perl -F -ane'$h{$_}++ for(@F);for(@F){if($h{$_}>1){$h{$_}=1;print}}'
这将适用于任何系统上的任何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
with 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//1231/;tb' -e 's/.//;/^n/b e' -e 'b b' -e ':e' -e 's/.//'
概念
- 将字母的出现次数限制为最多两次
':a' -e 's/((.).*2.*)2/1/;ta'
- 使用持有人缓冲区
G
添加换行符(在末尾) 测试第一个字符是否存在两次(在第二行之前),如果是,请将其放在第二行中并删除字母的第二次出现
:b" -e '/^(.)(.*)1(.*n.*)/s//1231/;tb
删除第一个字符
s/.//
- 如果第一个字符是换行符,请转到脚本末尾,删除换行符(并打印)
/^n/b e'
...-e ':e'
- 如果不是循环
-e 'b b'
这可能对你有用(GNU sed):
sed -r ':a;s/n*(([^n]).*)2/n1/;ta;s/n(.)[^n]*/1/g' file
在删除重复字符时,使用唯一的标记(即n
.然后删除所有与标记无关的字符(以及标记),以仅保留那些有重复项的字符。