Sunday, 6 December 2015

More textile manipulation with sed and bash

One of my colleagues was looking for a way to manipulate an XML file, using sed on Linux.

In essence, he wanted to remove an XML tag at the current end of the file, and insert a new line BELOW the current end of the file, making the new line the new end of the file :-)

Here's a mockup of my solution.

I used a file called foobar.bak as my input file, mainly so that I could quickly see/compare the changes between input and output.

Input file - foobar.bak

The quick brown fox
Jumped over the lazy dog
In the pouring rainfall


( Note the tab characters; they're there because my friends' XML file had tabs for pagination )

Script - replace.sh

#!/bin/bash
cp foobar.bak foobar.txt

file="foobar.txt"
replace="fall"
insert="That is all"
sed -i'' "$ s/$replace//g" $file
sed -i'' "$ a\ \t \t$insert" $file


In essence, I'm copying the foobar.bak file to foobar.txt each time I run the script, meaning that I preserve the original file :-)

I'm then setting some variables, one for the filename, one for the character to be replaced, and one for the new line.

I then use sed to replace ( remove ) the to-be-replaced string.

Finally, I again use sed to insert a new line - note that I'm using sed twice, mainly because I couldn't work out how to replace and then insert a blank line in sed I even messed about with ^M characters, but to no avail.

Output file - foobar.txt

The quick brown fox
Jumped over the lazy dog
In the pouring rain
    That is all


Again, note the tabs for pagination ( they're handled with \t above ).

*UPDATE*

I then thought about the two occurrences of sed again, and came up with this improvement: -

#!/bin/bash
cp foobar.bak foobar.txt

file="foobar.txt"
replace="fall"
insert="That is all"
sed -i'' "$ s/$replace/\n\t\t$insert/g" $file


which has the same effect, but does everything in a single sed statement :-)



No comments: