Stephopolis
Stephopolis

Reputation: 1795

Remove unwanted new lines in vim

I have a set of data in a file that looks like this:

1  >1st 
2  APOTPOTOPTOA
3  POTPAOTPOAOP
4  OTAAPAOAPOTA
5  APOTA
6  >2nd 
7  POATPOAOOTPA
8  OOPTPAOPOPPO
9  OOTPPOPOAOPO
10 PT

And I want it to look like this:

1 >1st
2 APOTPOTOPTOAPOTPAOTPOAOPOTAAPAOAPOTAAPOTA 
3 >2nd 
4 POATPOAOOTPAOOPTPAOPOPPOOOTPPOPOAOPOPT  

So in vim I tried:

%s/[POTA]\n[POTA]/

but that isn't just getting rid of new lines, it is affecting other characters in the lines. It is deleting the first and the last character as well as the new line. What am I missing here?

Upvotes: 0

Views: 97

Answers (3)

Alan Gómez
Alan Gómez

Reputation: 378

This regex can do the job:

:%s/\(\n>.*\n\|>.*\n\)\|\n/\1

Must be needed to assure that >.*\n match >1st line because is not proceeded by a intro character.

Upvotes: 0

Peter Rincker
Peter Rincker

Reputation: 45117

Simple case

Use :join with :global should do the trick.

:g/^>/+j! 4
  • :g/{pat}/{cmd} Run {cmd} on every line matching pattern, {pat}.
  • :join will join lines together
  • :join! will join without touching the white-space.
  • :join takes a range our range is the next line +1 which can be abbreviated +
  • :join can take the number of lines to join. In this case 4

Generalized Case

For an arbitrary number of lines use the :join command with a more complex range.

:v/^>/-2/^[^>]/,j!

Overview

:join! the current line with the line above it if the line does not start with > or if the previous line starts with >.

Glory of details

  • :v/{pat}/{cmd} will run {cmd} on every line not matching {pat}
  • The :j command takes a range: -2/^[^>]/,
  • :j! means join without messing with whitespace
  • The range is -2/^[^>]/,
  • This reads start 2 line above the current line then find the next line not starting with >
  • The ending range is the current line, .. However . can be assumed so leave it blank.

For more help see:

:h :j
:h :g

Upvotes: 4

Lukas Eklund
Lukas Eklund

Reputation: 6138

You need to capture the letter prior to the newline and the first letter on the next line as long as it's not a '>':

%s/\([AOPT]\)\n\([^>]\)/\1\2/g

Upvotes: 1

Related Questions