Como trocar dois padrões no lugar com 'sed'?

0

Estou usando o comando sed para alterar <active>true para <active>false em um arquivo xml. Agora, se eu usar

sed 's/<active>true/<active>false/g' file.xml > file.xml

apaga completamente o conteúdo do meu arquivo. Ao usar >> em vez de > , ele anexa a saída no final, como esperado.

  1. Como conseguir o que quero fazer?
  2. Por que > está se comportando de forma tão estranha?
  3. O que eu realmente quero fazer é alterar <active>true para <active>false se <active>true estiver presente e vice-versa se <active>false estiver presente no arquivo. Existe algum comando que possa fazer isso ou eu preciso escrever um script com if-else como meu plano original?
por monster 30.07.2018 / 19:34

1 resposta

1

O comportamento de > é explicado em este Unix & Resposta do Linux SE . O exemplo lá é cat test.txt > test.txt e a explicação é:

The first thing that happens is bash opens test.txt, which truncates the file. It is now empty, before cat is executed with test.txt as an argument.

Seu sed '…' file.xml > file.xml aciona o mesmo comportamento.

Solução bastante simples com um único sed :

sed -i 's/<active>true/<active>DUMMY/g
   s/<active>false/<active>true/g
   s/<active>DUMMY/<active>false/g' file.xml

A opção -i resolve seu problema com o arquivo sendo truncado. O comando transforma <active>true em <active>false e vice-versa. Note que você não pode usar apenas

s/<active>true/<active>false/g;s/<active>false/<active>true/g

porque a segunda parte não sabe se false é a% originalfalse ou a true original acabou de se transformar em false . Isso faz com que todas as coincidências true ou false acabem como true . Por esse motivo, usei a substituição temporária DUMMY . Talvez exista uma maneira melhor de fazer isso, ainda não sei.

A única condição é que a string <active>DUMMY não pode aparecer no arquivo original. Se aparecer, use outra string fictícia que não aparece com certeza.

    
por 30.07.2018 / 20:17