Eu tenho um arquivo com o seguinte conteúdo:
<username><![CDATA[name]]></username>
<password><![CDATA[password]]></password>
<dbname><![CDATA[name]]></dbname>
e preciso criar um script que altere o "nome" na primeira linha para "alguma coisa", a "senha" na segunda linha para "outra coisa" e o "nome" na terceira linha para "alguma coisa diferente". Como não posso confiar na ordem em que ocorrem no arquivo, não posso simplesmente substituir a primeira ocorrência de "nome" por "algo" e a segunda ocorrência de "nome" por "algo diferente". Na verdade, preciso fazer uma pesquisa pelas seqüências de caracteres circundantes para ter certeza de que estou encontrando e substituindo a coisa correta.
Até agora, tentei este comando para localizar e substituir a primeira ocorrência de "nome":
sed -i "s/<username><![CDATA[name]]><\/username>/something/g" file.xml
no entanto, não está funcionando, então acho que alguns desses personagens podem precisar ser escapados etc.
Idealmente, eu adoraria poder usar regex para corresponder apenas às duas ocorrências de "nome de usuário" e substituir apenas o "nome". Algo assim, mas com sed
:
<username>.+?(name).+?</username>
e substitua o conteúdo entre parênteses por "alguma coisa".
Isso é possível?
fonte
Respostas:
Acho que é isso que você está procurando.
Explicação:
\1
,\2
etc. na segunda parte, são referências ao i-ésimo grupo capturado na primeira parte (a numeração começa com 1)-E
permite expressões regulares estendidas (necessárias para+
e agrupamento).fonte
(original name) + "-E"
.\(
e em\)
vez de(
e)
.O
/username/
before antess
diz ao sed para trabalhar apenas em linhas contendo a string 'username'.fonte
Se
sed
não for um requisito difícil, use melhor uma ferramenta dedicada.Se o seu arquivo for XML válido (não apenas essas três tags de aparência XML), você poderá usar o XMLStarlet :
O exposto acima também funcionará em situações que seriam difíceis de resolver com expressões regulares:
Breve demonstração do acima exposto:
fonte
Você precisa citar
\[.*^$/
na parte da expressão regular dos
comando e\&/
na parte de substituição, além de novas linhas. A expressão regular é uma expressão regular básica e, além disso, é necessário citar o delimitador para os
comando.Você pode escolher um delimitador diferente para evitar a cotação
/
. Você precisará citar esse caractere, mas geralmente o ponto de alterar o delimitador é escolher um que não ocorra no texto a ser substituído ou no texto de substituição.Você pode usar grupos para evitar a repetição de algumas partes no texto de substituição e acomodar variações nessas partes.
fonte
Você pode simplesmente usar endereços como no número anterior a "s", que indica o número da linha.
Além disso, o número no final indica
sed
para substituir a segunda correspondência, em vez de substituir a primeira correspondência.fonte
Para substituir a palavra "nome" pela palavra "alguma coisa", use:
Isso substituirá todas as ocorrências da palavra especificada.
Até agora, tudo é gerado na saída padrão, você pode usar:
para salvar as alterações em outro arquivo.
fonte
para substituir o valor em um arquivo de propriedades
fonte