O problema é que, como é, o regex pode combinar palavras parciais. No exemplo que você mostra, ele está combinando o i
no final de uma palavra com o i
no início do próximo. A solução é insistir que o regex corresponda a palavras inteiras:
$ echo "abc abc def ghi ijk ijk" | sed 's/\<\([a-z][a-z]*\)\> \<\>//g'
abc def ghi ijk
No GNU sed, \<
corresponde no início de uma palavra e \>
corresponde ao final de uma palavra.
Correspondências mais complexas
No exemplo da pergunta, o regex estava correspondendo em um único caractere repetido, i i
. Aqui está um exemplo onde corresponde a oat oat
:
$ echo "smoat oats" | sed 's/\([a-z][a-z]*\) //g'
smoats
Isso é, novamente, corrigido insistindo em palavras inteiras:
$ echo "smoat oats" | sed 's/\<\([a-z][a-z]*\)\> \<\>//g'
smoat oats
Simplificação
Como as transições de alfabeto para espaço sempre marcam um limite de palavra, a parte da regex acima que usa \> \<
é desnecessária porque a regex requer que os caracteres em ambos os lados sejam alfabéticos. Assim, poderíamos usar:
$ echo "smoat oats" | sed 's/\<\([a-z][a-z]*\) \>//g'
smoat oats
Documentação
Para mais informações sobre as sutilezas do sed e suas expressões regulares, recomendo o tutorial do Grymoire . A referência final para o GNU sed é o manual do GNU sed .