Lolidas
Lolidas

Reputation: 13

GVim Command / Script to delete lines from a set of 4

This post could count as duplicate , but i have not found any relevant answer in previous threads. I have a large (6 GB) text file and i wish to remove every 3rd and 4th line in a set of 4 lines . For example , the following

line1
line2
line3
line4
line5
line6
line7
line8

needs to be converted to this

line1
line2
line5
line6

Is there any vim script / command to remove those lines ? It could be also in multiple passes . 1 pass to delete the 3rd lines (in a set of 4 (line1,line2,line3,line4)) and another pass to delete again the 3rd lines (previously 4th ones , in a set of 3 (line1,line2,line3)) .

The commands :g/^/+1 d3 is close to what i want but it also removes the second lines .

Upvotes: 1

Views: 240

Answers (3)

pozitron57
pozitron57

Reputation: 165

UPDATE: It is a bad approach for large files, it needs ~3 sec for a 6MB file to perform a substitution.


This approach works in vim. Using regular expression, you find 4 lines and substitute them with first two lines of these 4. Works for a long file as well. Doesn't work for last 1–3 lines if there is a remainder of division of total lines number by 4.

:%s#\(^.*\n^.*\)\n^.*\n^.*\n#\1\r#g

Explanation:

:%s — substitute in the whole file, # used as a delimiter

\(^.*\n^.*\)\(\) select two lines that will be used later as \1; \n stands for linebreak; ^ for the beginning of the line; .* for any symbol repeated as much times as possible before the linebreak

\n — linebreak after the second line

^.*\n^.*\n — next two lines to be deleted

\1\r — substitute for lines with first two lines and add a linebreak \r

g — apply to the whole file

Remove each 3rd and 4th lines

Upvotes: 0

janos
janos

Reputation: 124646

If you have GNU sed, you can filter the buffer through this pipeline:

sed -e '0~4d' | sed '0~3d'

The first sed deletes every 4th line, the second deletes every 3rd line. This has the desired effect.

To pipe the current buffer through this command, enter this in command mode:

%!sed -e '0~4d' | sed '0~3d'

The % selects the range of lines to pass to a command (% means all lines, the entire buffer), and !cmd is the command to pipe through.

To perform this outside of vim, run these two steps:

sed -ie '0~4d' file
sed -ie '0~3d' file

This will modify the file, in two steps.

Upvotes: 2

Peter Rincker
Peter Rincker

Reputation: 45117

Alternatively you can also use Awk.

awk 'NR%4==3||NR%4==0{next;}1' file.txt > output.txt

To do this via Vim:

%!awk 'NR\%4==3||NR\%4==0{next;}1'

Upvotes: 1

Related Questions