Sed

String manipulation is a skill that is useful almost on daily basis for most IT professionals.

Search, replace, count, filter, order text files from the command line make the process repeatable and fast, without too much clickety-click.

Awk, sed, sort, cut, uniq are powerful tools to master.

Today my focus is on sed that helped me during the migration to the new theme of my website

sed (stream editor) is a non-interactive command-line text editor. 

The problem

I decided to change the theme of ifconfig.it from blackburn to Tranquilpeak.

The problem is the two themes use a different shortcode for images.

Blackburn uses fluid_imgs:

{{< fluid_imgs 
  "pure-u-1-2|images/image.png"
>}}

Tranquilpeak uses image classes:

 {{< image classes="fancybox center clear" src="images/image.png" thumbnail="images/image.png" thumbnail-width="50%" group="group:images" >}}
Warning

How to migrate two hundred posts to the new sintax?

The solution

First things first, I need to get rid of two lines on my .md files.

{{< fluid_imgs 
>}}

That's the easy part:

sed -i 's/^{{< fluid_imgs//g' *.md
sed -i 's/^>}}//g' *.md

Now I focus on the line the includes the actual path of the image:

"pure-u-1-2|images/image.png"

I need to extract the image path }images/image.png and replace what comes before and after.

Sed can assign to a variable the text mathing the regexp inside the parenthesis and use it later.

Lets see the details.

The }yellow part is used to match the line to be replaced.

sed -i 's/}.*\"pure-u-.-.|\(.*\)"/g' *.md

In }purple a detail of the text that will be included in the variable:

sed -i 's/.*\"pure-u-.-.|\}(.*\)/g' *.md

In }green the new text that will replace the line:

sed -i 's/.*\"pure-u-.-.|\(.*\)"/}/g' *.md

In }purple again a detail of how the text assigned to the variable is used:

sed -i 's/.*\"pure-u-.-.|\(.*\)"/{{< image classes="fancybox center clear" src=\">}}}\1/g' *.md

The final result is the line changed from this

"pure-u-1-2|images/image.png"

to this

{{< image classes="fancybox center clear" src="images/image.png" thumbnail="images/image.png" thumbnail-width="50%" group="group:images">}}

We can test on bash with one command:

echo '"pure-u-1-2|images/image.png"' | sed -i 's/.*\"pure-u-.-.|\(.*\)"/{{< image classes="fancybox center clear" src=\"\1\" thumbnail=\"\1\" thumbnail-width="50%" group="group:images">}}/g'

And the run for all .md files:

sed -i 's/.*\"pure-u-.-.|\(.*\)"/{{< image classes="fancybox center clear" src=\"\1\" thumbnail=\"\1\" thumbnail-width="50%" group="group:images">}}/g' *.md

Wrap up

Sed is not easy to learn and it requires some regex skills that sometimes can be challenging.

Does it worth the time to learn? In my opinion it totally does. During my career I saw people spending hours with search&replace on text editors or spreadsheets. My personal preference goes to the CLI tools whenever I can avoid using the mouse.

Source: XKCD