ThG
ThG

Reputation: 2401

Vim howto insert a blank line before each change of pattern at the beginning of the lines?

Let us say I have a list such as :

Foo : 1st chapter
Foo : 2nd chapter
Bar : 1st chapter
Bar : 2nd chapter
Bar : 3rd chapter
Qux : 1st chapter

I want to insert a blank line (except before the first line, of course) each time a line begins with a different pattern (here 3 letters, but it could be 4-digit years : 2010, 2011, 2012, etc…) in order to have :

Foo : 1st chapter
Foo : 2nd chapter

Bar : 1st chapter
Bar : 2nd chapter
Bar : 3rd chapter

Qux : 1st chapter

How should I proceed ? Thanks in advance...

Upvotes: 1

Views: 839

Answers (3)

ib.
ib.

Reputation: 28934

In order to accomplish this task, one can use a single :global command inserting a blank after every line that does not start with the same word as the immediately following line:

:g/^\(\w\+\).*\n\1\@!./pu_

Upvotes: 4

Peter Rincker
Peter Rincker

Reputation: 45087

Awk to the rescue!

awk 'x != $1 { if(NR > 1)  print ""; x = $1 } {print}' file.txt > save-me.txt

Overview:

  • x != $1 { ... } run the block when variable x does not equal the first field aka $1
  • if(NR > 1) print ""; print an blank space except on the first record.
  • x = $1 set x to be equal to the first field, $1
  • {print} is shorthand for print the current record

You can filter text from Vim via a filter command like :%!sort. So to answer the proposed question you can do the following:

:%!awk 'x \!= $1 { if(NR > 1) print ""; x = $1 } {print}'

Overview:

  • % is shorthand for a range of the whole file, aka 1,$
  • There is no filename in the example, that is because the lines represented by the range are being feed in via stdin.
  • The output will replace the text in the range.
  • You will have to escape any ! with \!

See the following for more information on Vim's filtering

:h filter
:h :range!
:h :!

Upvotes: 1

kev
kev

Reputation: 161614

:let x='Foo' | g/^/ let y=split(getline('.'))[0] | if x!=y | s/^/\r/ | let x=y | endif

For simplicity: You can let x='' then :1d

Upvotes: 1

Related Questions