Aman Jain
Aman Jain

Reputation: 11317

vim -- How to read range of lines from a file into current buffer

I want to read line n1->n2 from file foo.c into the current buffer.

I tried: 147,227r /path/to/foo/foo.c

But I get: "E16: Invalid range", though I am certain that foo.c contains more than 1000 lines.

Upvotes: 70

Views: 37961

Answers (7)

joeytwiddle
joeytwiddle

Reputation: 31285

You can do it in pure Vimscript, without having to use an external tool like sed:

:put =readfile('/path/to/foo/foo.c')[146:226]

Note that we must decrement one from the line numbers because arrays start from 0 while line numbers start from 1.

Disadvantages: This solution is 7 characters longer than the accepted answer. It will temporarily read the entire file into memory, which could be a concern if that file is huge.

Upvotes: 34

raj
raj

Reputation: 131

Other solutions posted are great for specific line numbers. It's often the case that you want to read from top or bottom of another file. In that case, reading the output of head or tail is very fast. For example -

:r !head -20 xyz.xml

Will read first 20 lines from xyz.xml into current buffer where the cursor is

:r !tail -10 xyz.xml 

Will read last 10 lines from xyz.xml into current buffer where the cursor is

The head and tail commands are extremely fast, therefore even combining them can be much faster than other approaches for very large files.

:r !head -700030 xyz.xml| tail -30

Will read line numbers from 700000 to 700030 from file xyz.xml into current buffer

This operation should complete instantly even for fairly large files.

Upvotes: 13

Justin
Justin

Reputation: 56

A range permits a command to be applied to a group of lines in the current buffer.

So, the range of read instruction means where to insert the content in the current file, but not the range of file that you want to read.

Upvotes: 2

DigitalAce69
DigitalAce69

Reputation: 361

I just had to do this in a code project of mine and did it this way:

In buffer with /path/to/foo/foo.c open:

:147,227w export.txt

In buffer I'm working with:

:r export.txt

Much easier in my book... It requires having both files open, but if I'm importing a set of lines, I usually have them both open anyway. This method is more general and easier to remember for me, especially if I'm trying to export/import a trickier set of lines using g/<search_criteria/:.w >> export.txt or some other more complicated way of selecting lines.

Upvotes: 4

PaulB
PaulB

Reputation: 382

You will need to:

:r /path/to/foo/foo.c
:d 228,$
:d 1,146

Three steps, but it will get it done...

Upvotes: 2

boxxar
boxxar

Reputation: 11433

:r! sed -n 147,227p /path/to/foo/foo.c

Upvotes: 103

Stewart Johnson
Stewart Johnson

Reputation: 14449

The {range} refers to the destination in the current file, not the range of lines in the source file.

After some experimentation, it seems

:147,227r /path/to/foo/foo.c

means insert the contents of /path/to/foo/foo.c after line 227 in this file. i.e.: it ignores the 147.

Upvotes: 23

Related Questions