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]