Como inserir texto entre dois padrões de conjunto com sed?

1

Eu preciso inserir texto entre dois padrões definidos em um grande conjunto de arquivos.
Preciso alterar todas as linhas com este formulário:

<a href="/entry/someFile">

Para isso:

<a href="/entry/someFile.xhtml">

Eu tenho tentado escrever um comando sed para realizar isso, mas estou achando muito difícil.

Eu sei que preciso usar href="/entry/ e "> como delimitadores, mas não entendo como usar sed para inserções / substituições de texto mais complicadas.

edit: percebo que não estava claro no meu post original. Os padrões inalterados são href="/entry/ e "> . "someFile" pode ser qualquer nome de arquivo.

    
por Daniel Sweet 08.04.2018 / 20:21

2 respostas

1

Para uma solução sed , veja mais abaixo nesta resposta.

Supondo que os a são parte de um documento XML bem formado e que você deseja anexar .xhtml ao valor de suas tags href quando os valores existentes começarem com /entry/ :

xml ed -u '//a[starts-with(@href, "/entry/")]/@href' \
       -x 'concat(../@href,".xhtml")' file.xml >file-new.xml

Isso usa XMLStarlet (às vezes instalado como xmlstarlet em vez de apenas xml ) e ele encontrará o% relevantea nós e acrescentar .xhtml aos seus atributos href , independentemente de onde no documento eles ocorrem.

O resultado é salvo em um novo arquivo aqui, mas você pode usar xml ed --inplace ... para editar o arquivo no lugar depois de ter certeza de que funciona.

Teste:

$ cat file.xml
<?xml version="1.0"?>
<root>
  <a href="/entry/someFile1"/>
  <a href="/entry/someFile2"/>
  <a href="/entry/someFile3"/>
</root>

$ xml ed -u '//a[starts-with(@href, "/entry/")]/@href' -x 'concat(../@href,".xhtml")' file.xml
<?xml version="1.0"?>
<root>
  <a href="/entry/someFile1.xhtml"/>
  <a href="/entry/someFile2.xhtml"/>
  <a href="/entry/someFile3.xhtml"/>
</root>

Usando sed (o que você não usa normalmente em um arquivo XML bem formado):

sed 's|<a href="/entry/[^"]*|&.xhtml|g' file.xml

Isso corresponde à string <a href="/entry/ seguido por qualquer número de caracteres que não são " (esse seria o nome do arquivo). Essa parte inteira correspondente é então substituída por si mesma e pela string .xhtml .

Com sed -i , isso tornaria a modificação em vigor.

Teste (no mesmo arquivo acima):

$ sed 's|<a href="/entry/[^"]*|&.xthml|g' file.xml
<?xml version="1.0"?>
<root>
  <a href="/entry/someFile1.xhtml"/>
  <a href="/entry/someFile2.xhtml"/>
  <a href="/entry/someFile3.xhtml"/>
</root>
    
por 08.04.2018 / 20:39
0

sed pode ser muito complicado, mas para as suas necessidades é fácil de usar tente:

sed -i 's/<a href=".*">/<a href="/some/link/">/g' yourfile.html

A sintaxe é fácil:

sed -i 's/stringt before replacing/string after replacing/g'

o .* é o caractere curinga corresponde a qualquer uso no local necessário

Talvez você deva copiar o arquivo antes de usar o sed. o -i altera seu arquivo e não cria um novo:

-i [SUFFIX], --in-place[=SUFFIX] edit files in place (makes backup if SUFFIX supplied)

o g no final substitui todas as correspondências no arquivo

se você quiser alterar apenas a primeira correspondência no seu arquivo, use:

sed -i '0,/<a href=".*">/{s/<a href=".*">/<a href="/some/link/">/}' yourfile.html

mesma sintaxe:

sed -i '0,/string before/{s/string brefore/string after/}'
    
por 08.04.2018 / 20:56