Seu regexp
sed 's#&*;##g' <file>
não faz o que você acha que faz. O caractere *
é um multiplicador que diz que o caractere precedente é repetido 0 ou mais vezes. O caractere anterior é &
, portanto, isso corresponderia, por exemplo, &&&;
e ;
( &
é escrito 0 vezes antes de ;
! Isto é o que está correspondendo em seus casos de teste) mas não o que você quer neste caso.
Você precisa especificar " qualquer caractere" antes do multiplicador, que é representado por um único ponto, .
.
$ echo 'Text:3' | sed 's#&.*;##g'
Text3
Esse foi o primeiro problema. O segundo é o conceito de correspondência "gananciosa": sed
verá o primeiro &
e tentará combinar a maior sequência possível. Se você tiver várias entidades HTML em uma única linha, isso seria um problema, pois:
$ echo 'Text:3 and some more text å and end' | sed 's#&.*;##g'
Text and end
Se você quiser ver uma correção no contexto sed
, poderá procurar o caractere final da entidade correspondendo qualquer número de " não ;
" antes de um fechamento ;
fazendo:
$ echo 'Text:3 and some more text å and end' | sed 's#&[^;]*;##g'
Text3 and some more text and end
Você ainda terá problemas com o uso legítimo do sinal de e comercial ( &
) no texto (bem, &
é o verdadeiro uso "legítimo", mas o mundo real nem sempre é tão parsável quanto o ideal ) e combinando muito, mas isso explica porque o sed
está se comportando da maneira como funciona.