Como substituo esse padrão por uma nova linha dentro dele? [duplicado]

1

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?

    
por DisplayName 24.01.2016 / 18:50

3 respostas

2

POSIXly:

$ sed -e '/<!--/{
  $!N
  s/.*on //
}' <in >out
    
por 24.01.2016 / 19:01
2

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 ...

    
por 24.01.2016 / 18:56
1

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".

    
por 24.01.2016 / 19:06