Wednesday 30 August 2017

Add a new line after a string match using vim or sed

In this brief article I'd like to demonstrate how we can add a new line after a character match using vim and sed.

Let's take an example scenario where I have a file comprised of the 'ls -l' output of the /etc/ directory and I would like to insert a new line between each line in the command output.

My file looks like this:

[ssuri@:~] $ cat dir_list | head
drwxr-xr-x.  2 root  root    4096 Jan 11  2010 popt.d
drwx------.  2 root  root    4096 Jun  3  2011 cron.weekly
drwxr-xr-x.  3 root  root    4096 Jan 16  2014 pkcs11
drwxr-xr-x.  2 root  root    4096 May  7  2014 gnupg
drwxr-xr-x.  3 root  root    4096 Jun 19  2014 hal
drwxr-xr-x.  5 root  root    4096 Dec 12  2014 pm
drwxr-xr-x.  3 root  root    4096 Dec 12  2014 xdg
drwxr-xr-x.  2 root  root    4096 Dec 12  2014 makedev.d
drwxr-xr-x.  3 root  root    4096 Dec 12  2014 sane.d
drwxr-xr-x.  2 root  root    4096 Dec 12  2014 redhat-lsb


First let's insert a new line using vim. The vim command used here is :%s/^drw/\rdrw/g

The output of this vim command will modify the file as follows:


  2 drwxr-xr-x.  2 root  root    4096 Jan 11  2010 popt.d
  3
  4 drwx------.  2 root  root    4096 Jun  3  2011 cron.weekly
  5
  6 drwxr-xr-x.  3 root  root    4096 Jan 16  2014 pkcs11
  7
  8 drwxr-xr-x.  2 root  root    4096 May  7  2014 gnupg
  9
 10 drwxr-xr-x.  3 root  root    4096 Jun 19  2014 hal
 11
 12 drwxr-xr-x.  5 root  root    4096 Dec 12  2014 pm
 13
 14 drwxr-xr-x.  3 root  root    4096 Dec 12  2014 xdg
 15
 16 drwxr-xr-x.  2 root  root    4096 Dec 12  2014 makedev.d
 17
 18 drwxr-xr-x.  3 root  root    4096 Dec 12  2014 sane.d
 19
 20 drwxr-xr-x.  2 root  root    4096 Dec 12  2014 redhat-lsb

(Don't mind the line numbers. they're just there because I had the set nu flag on to show line numbers)

Let me break down the expression for you.

% -> operates on the entire file.
s  -> search for an expression.
^drw -> search for lines beginning with the string drw.
\rdrw -> \r is the carriage return. In vim this will insert a new line. 
g -> Perform a global search and replace.


So, the expression %s/^drw/\rdrw/g will walk through the entire file, look for the lines beginning with the string drw and replace them with a new line followed the line beginning with the string drw throughout the file.


Using vim is great but you'll have to manually edit the file. So let's look at sed if you'd like to accomplish this task within a script.


[ssuri@:~] $ sed 's/^drw/\ndrw/g' dir_list

drwxr-xr-x.  2 root  root    4096 Jan 11  2010 popt.d

drwx------.  2 root  root    4096 Jun  3  2011 cron.weekly

drwxr-xr-x.  3 root  root    4096 Jan 16  2014 pkcs11

drwxr-xr-x.  2 root  root    4096 May  7  2014 gnupg

drwxr-xr-x.  3 root  root    4096 Jun 19  2014 hal

drwxr-xr-x.  5 root  root    4096 Dec 12  2014 pm

drwxr-xr-x.  3 root  root    4096 Dec 12  2014 xdg

drwxr-xr-x.  2 root  root    4096 Dec 12  2014 makedev.d

drwxr-xr-x.  3 root  root    4096 Dec 12  2014 sane.d

drwxr-xr-x.  2 root  root    4096 Dec 12  2014 redhat-lsb


The sed expression is very similar to the expression we used in vim the only difference being that in case of sed we'll use \n to insert a new line instead of \r.

I hope this article was useful to you and I thank you for reading.

No comments:

Post a Comment

Using capture groups in grep in Linux

Introduction Let me start by saying that this article isn't about capture groups in grep per se. What we are going to do here with gr...