Como sed
em seu modo padrão opera linha a linha, uma abordagem (admitidamente ofuscada) seria substituir os caracteres de nova linha por algo mais (como o caractere NULL \x00
) antes de alimentar o o conteúdo em sed
:
tr '\n' '\x00' <my_file
sed
, em seguida, vê o conteúdo como uma linha. No entanto,
sed -e 's/<!-- my comment -->.*<!-- \/my comment end -->//'
não funcionará devido à natureza de correspondência gulosa de sed
. Poderíamos implementar uma correspondência não-ávida combinando tudo dentro do comentário até o primeiro caractere <
, mas isso só funcionaria se os comentários HTML não tivessem permissão para conter <
caracteres (e, em particular, outras tags HTML) , o que não podemos assumir.
Para resolver isso, converteremos a seqüência <!
em um único caractere não usado em outro lugar no arquivo, para o qual podemos construir uma correspondência não-gulosa. Escolheremos o caractere especial \x01
para essa finalidade, que convertemos de volta para <!
após a correspondência não desejada:
sed -e $'s/<!/\x01/g' -e $'s/\x01-- my comment -->[^\x01]*\x01-- \/my comment end -->//g'
(observe o uso da sintaxe do shell $''
em vez de ''
para passar o caractere de byte único literal \ x01 para sed
)
Em um terceiro estágio, os caracteres NULL são convertidos em novas linhas:
tr '\x00' '\n'
E, finalmente, as linhas vazias são suprimidas por outra invocação de sed
:
sed -e '/^$/d'
Em resumo,
tr '\n' '\x00' <my_file |sed -e $'s/<!/\x01/g' -e $'s/\x01-- my comment -->[^\x01]*\x01-- \/my comment end -->//g' |tr '\x00' '\n'|sed -e '/^$/d'
Existem soluções mais elegantes se você optar por usar ferramentas diferentes ( awk
ou perl
one-liners) em vez de sed
, como:
perl -0pe 's/<!-- my comment -->.*?<!-- \/my comment end -->//gs' my_file