POSIXly:
$ sed -e '/<!--/{
$!N
s/.*on //
}' <in >out
Se eu tiver um arquivo de texto com este conteúdo:
someline
<!--\
file first read on 2015/01/11
E eu quero excluir <!--\
e tudo até o que vem depois de "on", como faço isso? A saída esperada seria esta com o exemplo acima:
someline
2015/01/11
Não consigo criar um padrão que extraia datas, porque 2015/01/11
pode ser apenas Sunday
ou Yesterday
ou quase qualquer outra coisa. read
também pode ser qualquer coisa. Eu tentei isso com BSD sed
:
sed 's/<!--\
file first .* on//g'
Mas quando eu executo este comando, recebo este erro:
sed: 1: "s/<!--\
file f ...": unterminated substitute pattern
Então, tentei a barra invertida escapando de <
e !
, mas recebi o mesmo erro de "padrão substituto não terminado". Eu tentei instalar o GNU sed e fazer a mesma coisa, exceto \n
, eu também tentei gsed 's/<!--:a;N;$!ba;s/\n/file first .* on//g'
, mas eu consegui:
gsed: -e expression #1, char 22: unknown option to 's'
Pode sed
não fazer isso? Se não, como faço com qualquer outra ferramenta / linguagem?
POSIXly:
$ sed -e '/<!--/{
$!N
s/.*on //
}' <in >out
O comando sed
a seguir deve fazer o que você deseja:
sed '/^<!--/{N; s/.*on *//}' inputfile
Primeiro, procuramos o regex <!--
no começo da linha, então usamos o comando N
para acrescentar a próxima linha a ele e deletar (substituir nada, na verdade) tudo até e com "on" .
Há pessoas afirmando que sempre que você usa um comando de letra maiúscula em sed
, como N
, está usando a ferramenta errada ...
O Perl pode ler o arquivo inteiro com -0777
, o modificador /s
torna .
newlines também:
perl -0777 -pe 's/<!--\.*?on //gs'
*?
é um "asterisco frugal", que significa "repetir zero ou mais vezes, mas corresponde à string mais curta possível".