Isso é bastante complicado de se fazer no sed, mas aqui está uma versão que pode funcionar desde que haja um caractere (eu escolhi %
) que nunca aparecerá na entrada. O caractere é usado para marcar.
Digamos que você tenha um arquivo de texto chamado words
com o seguinte conteúdo:
Will He beat Sit Down Boy Oh Not now Latch Wi, Qq or Spat? GNU Hurd, protocols on GNU Mach. The Hurd versus Unix.
O seguinte script bash
fará o trabalho:
cat words
sed 's/ [A-Z][A-Za-z]*[A-Za-z]\{2\}/%&/g' words|tee a
sed 's/\([.!?]\)%//g' a|tee b
sed 's/% [A-Za-z]*\([A-Za-z]\{2\}\)/ Derp/g' b|tee c
A saída dos itens acima será (eu separei cada um por nova linha):
Will He beat Sit Down Boy Oh Not now Latch Wi, Qq or Spat? GNU Hurd, protocols on GNU Mach. The Hurd versus Unix.
Will He beat% Sit% Down% Boy Oh% Not now% Latch Wi, Qq or% Spat?% GNU% Hurd, protocols on% GNU% Mach.% The% Hurd versus% Unix.
Will He beat% Sit% Down% Boy Oh% Not now% Latch Wi, Qq or% Spat? GNU% Hurd, protocols on% GNU% Mach. The% Hurd versus% Unix.
Will He beat Derpit Derpwn Derpoy Oh Derpot now Derpch Wi, Qq or Derpat? GNU Derprd, protocols on DerpNU Derpch. The Derprd versus Derpix.
Veja como funciona:
- A primeira linha apenas imprime o arquivo, então você vê a posição inicial.
- A segunda linha marca todas as palavras em maiúsculas que são precedidas por um espaço e são maiores que 2 caracteres com
%
. Assim, por exemplo, marqueLatch
como% Latch
. Observe o espaço, eu chamarei esta palavra-espaço. - A terceira linha removerá a marca de todas as palavras de espaço precedidas por um caractere que termina uma frase (para simplificar, escolhi apenas
.
,!
ou?
- você pode adicionar outras, como)
ou tais, se necessário) - A terceira linha fará a transformação
Derp
real, ou seja, substituirá todas as palavras de espaço marcadas com%
porDerpXX
,XX
sendo dois últimos caracteres dessa palavra-espaço
Observe que há detalhes técnicos que não foram abordados aqui, como:
- Isso funcionará apenas para palavras em ASCII dos EUA (por exemplo, não funcionará para todas as palavras em francês, como
Être
) - Outros caracteres talvez precisem ser considerados (por exemplo,
Oceans
in"Oceans Eleven"
considerou uma palavra, embora tenha"
na frente?) - Não funcionará para espaços em branco que não sejam de espaço (por exemplo, guias)
e assim por diante.
Para torná-lo apenas um script sed
, basta concatenar:
sed '
s/ [A-Z][A-Za-z]*[A-Za-z]\{2\}/%&/g
s/\([.!?]\)%//g
s/% [A-Za-z]*\([A-Za-z]\{2\}\)/ Derp/g
' words
Obviamente, no mundo real, eu não usaria sed
para fazer tarefas como essa. Então, novamente, eu provavelmente não teria tarefas como esta, também ...:)