Você pode fazer isso somente usando POSIX sed
? Sim:
sed -e 's/.^H//g' < data
onde ^H
é apenas um caractere de retrocesso literal. POSIX sed
usa expressões regulares básicas POSIX , que são definidas sobre bytes - caracteres de impressão ou não, eles não se importam, então isso se comporta da mesma forma como se ^H
fosse uma carta. Não há extensões envolvidas aqui. Observe que tudo o que você realmente quer fazer é remover os caracteres que foram retrocedidos, para que os grupos de captura em seu exemplo não sejam realmente necessários.
Você pode digitar o caractere de backspace na maioria dos casos com Ctrl + V Ctrl + H .
Eu acho que a pergunta latente que você tem é "como eu faço isso em um shell script?", onde um caractere de backspace literal pode ser desagradável para trabalhar (embora vim
aceite muito bem o mesmo Ctrl + V Ctrl + H para escrever um em). É aqui que a introdução que você vinculou usa tr
.
POSIX tr
suporta vários escape caracteres , incluindo o escape \b
simbólico para um caractere de retrocesso. Você pode salvar um caractere de retrocesso em uma variável e substituí-la na expressão sed
acima:
BACKSPACE=$(echo x | tr 'x' '\b')
sed -e "s/.$BACKSPACE//g" < data
Acabamos de dizer a tr
para substituir um x
pelo caractere de retrocesso e dar a ele um único x
como entrada. Isso funciona bem em todos os sistemas que eu tenho acesso, incluindo o Solaris. No entanto, printf
é também uma ferramenta definida por POSIX , e suporta os mesmos escapes:
BACKSPACE=$(printf '\b')
sed -e "s/.$BACKSPACE//g" < data
Isso é mais simples e direto que a versão tr
. Observe a citação dupla em torno da expressão sed
, para que não seja mais suprimida a interpolação de variáveis. Você também pode usar substituição de comandos para colocar o printf '\b'
in diretamente se você ' só vai usá-lo uma vez, em vez de usar uma variável.
Podemos verificar se isso funciona com hexdump
(ou hd
):
$ dash
$ hexdump -C data
00000000 62 08 62 6f 08 6f 6c 08 6c 64 08 64 0a |b.bo.ol.ld.d.|
$ BACKSPACE=$(printf '\b')
$ sed -e "s/.$BACKSPACE//g" < data | hexdump -C
00000000 62 6f 6c 64 0a |bold.|
Conforme desejado, o caractere de retrocesso e o caractere precedente apagado são removidos da saída ( 0a
é a nova linha de finalização).