Thursday, 20 June 2019

command line - How to exchange two patterns in place with `sed`?


I am using sed command to change true to false in an xml file. Now if I use


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

it completely erases the content of my file. While using >> instead of >, it appends output at the end like it is expected to do.



  1. How to achieve what I want to do?

  2. Why is > behaving so weirdly?

  3. What i actually want to do is change true to false if true is present and vice versa if false is present in file. Is there some command that can do it or do I need to write a script with if-else like my original plan?



Answer



The behavior of > is explained in this Unix & Linux SE answer. The example there is cat test.txt > test.txt and the explanation is:



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.



Your sed '…' file.xml > file.xml triggers the same behavior.


Quite straightforward solution with a single sed:


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

The -i option solves your problem with the file being truncated. The command turns true into false and vice versa. Note you cannot use just


s/true/false/g;s/false/true/g

because the second part cannot tell if any false is the original false or the original true just turned into false. This causes every matching true or false end up as true. For this reason I used the temporary DUMMY replacement. Maybe there is a better way to do it, I don't know it yet.


The only condition is the string DUMMY cannot appear in the original file. If it may appear, use another dummy string which doesn't appear for sure.


No comments:

Post a Comment

How can I VLOOKUP in multiple Excel documents?

I am trying to VLOOKUP reference data with around 400 seperate Excel files. Is it possible to do this in a quick way rather than doing it m...