Reading specific lines from a file into another file within Vi

If you need to read lines from another file into the file you are currently editing within the Vi text editor, you can do so by utilizing the editor's ability to execute an external command, e.g., a Linux/Unix shell command, by entering an exclamation mark followed by the external command. E.g., if I wanted to read the first 55 lines from the file ~/temp/lincoln.txt, I could e nter Vi's colon mode by hitting Esc followed by the colon character. I could then type r, which is the command used to read from another file. But, instead of immediately typing the file name, e.g. :r ~/temp/lincoln.txt, I could use the head utility to read the first fifty-five lines of the file by typing head -55 followed by the path to the file and the file name. E.g.:

:r !head -55 ~/temp/lincoln.txt

If, instead, I wanted to read the last 14 lines of the file, I could use the tail command.

:r !tail -14 ~/temp/lincoln.txt

If I wanted to include specific lines from the other file into the one I'm currently editing, e.g., lines 10 through 15, I could use the sed command as shown below.

:r !sed -n 10,15p ~/temp/lincoln.txt

The -n has the following meaning:

       -n, --quiet, --silent

              suppress automatic printing of pattern space

The p command for sed accepts an address range, in this case lines 10 to 15, and prints the current pattern space for those lines, so in this case the command entered in vi will insert lines 10 through 15 into the file I'm currently editing.

If I wanted to include all of the lines from a specific line number to the end of a file, I could use the command below:

:r !sed -n '10,$p' ~/temp/lincoln.txt

The dollar sign character, "$", represents the end of the file.

An alternative to calling an external command, such as sed, is to use a command like the one below:

:put =readfile('lincoln.txt')[10:15]

But, if I want to include lines 10 through 15, the above command won't do exactly what I want; it will include lines 11 through 16 because the first element in the array specifed within the square brackets starts at 0 rather than 1 while lines numbers in a file start at 1. So I I want lines 10 through 15 from the external file, I need to use the following command, instead:

:put =readfile('lincoln.txt')[9:14]

I.e., I need to decrement the starting and ending line numbers by one.

I can also use a similar command to read just a specific line from the external file. E.g., if I wanted to read in line 7 from that file, I could use the line below:

:put =readfile('lincoln.txt')[6]

Or, if I wanted to read the third line from the end of the file, I could use the command below:

:put =readfile('lincoln.txt')[-3]

If I wanted to read from the fourth to the last line in the file to the third to last line in the file, I could use the command below:

:put =readfile('lincoln.txt')[-4:-3]