You may have some experience with vi, or what is now known as Vim (which is when simply put—vi improved). All too often, I find that those first experiences have never been good ones or to be looked back upon with much fondness. Guiding you through the initially unfathomable regime of vi, we are going to make sure that you are the master of vi and you leave wanting to use this tool from the gods. vi is like everything else in the sense that you just need to stick with it in the early days and keep practicing. Remember how you persevered for many hours riding your bicycle as a toddler and became a master, despite a few bruised knees? I want you to persevere with vi too. We will start with a little command-line magic to make the whole command-line interface (CLI) experience a better one. We will then be ready to start our black-belt experience in vi.
In this chapter, we will go through the following topics:
CLI trickery – shortcuts that you will love
Vim and vi: In this section, you will learn to differentiate between these twins and meet their graphical cousin
Getting the .vimrc setup the way you like
Search and replace: In this section, you will learn how to quickly find and replace text within files from both inside and outside Vim
Learning to remove extraneous comments from a file with a few deft key strokes
So before we dice into the wonderful world of text editing that is vi, we will warm up with a few exercises on the keyboard. Linux is my passion, as is automation. I am always keen to create scripts to carry out tasks so that those tasks become repeatedly correct. Once the script is created and tested, we will have the knowledge and faith that it will run in the same way every time and we will not make mistakes or miss critical steps, either because it gets boring or we are working late on a Friday night and just want to go home. Scripting itself is just knowing the command line well and being able to use it at its best. This truth remains across all systems that you will work with.
On the command line, we may try a little more black magic by executing the following command:
$ cd dir1 || mkdir dir1 && cd dir1
With this, we have used the
cd command to enter the
dir1 directory. The double pipe or vertical bar indicates that we will attempt the next command only if the first command fails. This means that if we fail to switch to the
dir1 directory, we will run the
mkdir dir1 command to create it. If the directory creation succeeds, we then change into that directory.
|| part denotes that the second command will run only on the failure of the first. The
&& part denotes that the second command will run only if the first command succeeds.
The command history is a little more and hugely better than just an up arrow key! Consider the following commands:
$ mkdir dir1 $ cd !$
!$ part represents the last argument, so in this way, the second line evaluates to the following:
$ cd dir1
In this way, we can rewrite the initial command sequence, by combining both concepts, to create the following command:
$ cd dir1 || mkdir !$ && cd !$
We can repeat the last command as well as the last argument. More importantly, we can specify the start characters for the last command. If it was merely the last command, then the up arrow key would suffice. If we were working on a web server configuration, we may want to edit the configuration file with vi, start the service, and then test with a command-line browser. We can represent these tasks using the following three commands:
# vi /etc/httpd/conf/httpd.conf # service httpd restart w3m localhost
Having run these three commands in the correct order, hoping for success, we may notice that we still have issues and that we need to start re-editing the configuration file for Apache, the web server. We can now abbreviate the command list to the following:
# !v # !s # !w
!v command will rerun the last command in my history that begins with a
v, and likewise with
w. This way, we can appear to be terribly proficient and working really quickly, thus gaining more time to do what really interests us, perhaps a short 9 holes?
In a similar fashion to our first glance at the history using the
!$ symbols to represent the last argument, we can use
!?73. This would look for
73 anywhere as an argument or part of an argument. With my current history, this would relate to the date command we ran earlier. Let's take a look:
With my history, the sequence will expand to and run the following command:
$ date --date "73 days ago"
Looking at my command history from the last command run to the first, we search for
73 anywhere as a command argument. We make a note that we exclusively look for
73, meaning we are looking for the character
7 followed by the character
3. We have to then bear in mind that we would also match
733 if they existed in my history.
Having mastered a little of the Bash shell history functions, we should practice to make this second nature.
The command-line text editor vi was first written in 1976 and became part of the first release of BSD Unix in 1978. Even though it is command line driven and with no Graphical User Interface (GUI) or menu, a 2009 survey conducted by Linux Journal found that vi was the most popular editor, beating even gedit, the GUI GNOME editor, into second place. I am not averse to the GUI, but I find a GUI editor to be restrictive and slow. I can honestly say that the majority of, if not all, tasks can be performed by me more quickly in vi.
That being said, in CentOS, you will not find vi; vi is purely a default alias that is provided for convenience, and links to the
vim command. We can view this on my CentOS 6.5 console using the following command:
$ alias | grep vi
Vim is a contraction of Vi IMproved and was first publicly released in 1991 and authored by Bram Moolenaar, initially targeted at the Amiga system. It has been common in the Linux platform since the early 2000s. As the name suggests, it is based on vi and is improved; on CentOS, it is distributed with the
vim-enhanced package. These improvements are most commonly useful with the syntax-highlighting feature available for languages such as PERL, Python, and PHP. Another such improvement is that it can work traditionally on the command line or with a GUI frontend. To install the graphical interface for Vim, you will need to add the
vim-X11 package as follows:
# yum install -y vim-X11
One limitation, of course, is that you will require the X11 server to be running. In an enterprise, the server will often run without a GUI and you can connect using secure shell to a command-line shell only.
If you are new to vi, then using the graphical version can be helpful, as the menus also display the command-line shortcuts. To edit a file with vi or Vim on the command line, we can simply use a command similar to the following:
$ vi <filename-to-edit>
It is possible to use the graphical version of an editor when you are working on the CentOS desktop as follows:
$ gvim <filename-to-edit>
$ vimx -g <filename-to-edit>
As with many programs in Linux, Vim has the option to read settings from a run-control file. This can be centralized via the
/etc/vimrc file, or for each user via the
~/.vimrc file. With this file, especially with our own version, you can customize how Vim appears and controls its functionalities.
Firstly, we will look at line numbering. Often when we edit a file, we do so as the console has reported an error on a particular line just after we have tried running a script or starting a service; we know we have a syntax error. Let's say we want to go directly to the offending line
97 of the
test.php file. Then, we would duly type:
$ vi +97 test.php
This is assuming that we were in the same directory as our file. Similarly, should we want to go directly to the first occurrence of the word
install within the
readme file, we could issue the following command:
$ vi +/install readme
Then, as if by magic, we are transported to the correct line that we require. However, in the case of the word
search, the word that was
search is highlighted in color. If that is not desirable, then we can simply turn off that feature. Within Vim, we can type:
If there are settings that we want to make permanent within Vim, we can edit the
.vimrc file in our home directory. This is our own personal settings file and as such, changes made here will not affect anyone else. If we want to affect system-wide settings, then we can use the
/etc/vimrc file. Try adding the following line to the
~/.vimrc file to persistently disable the highlight
With this addition, each time we start Vim, the setting is ready for us. As we view our files though, from within Vim, we may prefer to have line numbering turned on. Sometimes this makes life easier, but other times, we may prefer to have line numbering off, especially in cases where we have lines starting with numbers (because the display can become confusing). To enable line numbering, run the following command:
To turn line numbering off, we can use the following command:
As before, we can always put the desired start-up value in the
.vimrc file. However, before we do this, let's look at key mappings within Vim and how we can create a shortcut to toggle line numbering on and off. We would like to create a mapping for the normal mode in Vim. This is the mode when we first enter Vim and we are not editing, just navigating the file; using the Esc key, we can always return to the normal mode. Execute the following command:
:nmap <C-N> : set invnumber<CR>
With this in place, we can now use the combination of Ctrl + N to toggle line numbering on and off. Now we are really starting to make some steam with this product, and you can gain some appreciation of why it is so popular. Before we make the final edit to the
.vimrc file, we will see how to navigate lines by number while in vi or Vim. Making sure that we are in the normal mode using the Esc key, we can use
2gg to navigate to line 2 of the current file; likewise,
234gg would go to line 234 and
gg would navigate to the end of the file. Simple but not simple enough; I would prefer to type the line number followed by the Enter key. For this, we map the Enter key to G. If we choose to use the Enter key without a preceding number, then we are taken directly to the end of the document, just as we would is we used the key G by itself. Execute the following command:
:nmap <CR> G
Now we simply type in the desired line number followed by Enter. This in turn is interpreted as the number followed by G. In this way, we can navigate easily to the correct line. We can persist this setting by adding the following text to the
.vimrc file, which should now read similar to the following text as we review all the settings made within this subsection:
set nohlsearch number nmap <C-N> : set invnumber<CR> nmap <CR> G
Now sit back and enjoy what you have achieved, remembering though that practice is the key to knowledge being retained.
So we are not exactly on a "search and destroy" mission, but if it helps by adding a little enjoyment to our learning, then we can embark upon a search and replace mission. Linux has a huge amount of power available on the command line and nothing less than the stream editor, sed. Even without entering the Vim editor, we can search for and replace text in a single file or even across multiple files. Not having to use an interactive editor opens up more administrative scope to us by being able to script updates across a single or many servers. The functionality we have in the
sed command is available to us for use from within Vim or as a standalone application. We will be learning in this subsection how to search for and replace text within files using sed and from within Vim, building skills that we can use across CentOS and other operating systems including OS X on the Mac.
Firstly, let's take a scenario that we have recently changed our company name and we need to change all the references of
Dungeons in a text document to
Dragons. Using sed, we could run the command directly from the console:
$ sed -i 's/Dungeons/Dragons/g' /path/file
This will read the file line by line, replacing all occurrences of the string
-i option allows for in-pace edits, meaning we edit the file without the need to redirect the output from sed to a new file. The
g option allows for the replacement to occur across all instances of
Dragon even if it appears more than once per line.
To do the same within Vim where we have the file open, run the following command:
The percent symbol is used to specify the range as the whole document; whereas if we use the following command, we would only search lines 3 through 12 inclusive of the search string. In this case, the range is said to be lines 3 to 12 whereas with
%, the range is the complete document.
The range can be very useful when perhaps we want to indent some code in a file. In the following line, we again search lines 3 through to 12 and add a Tab to the start of each line:
We have set the range in the previous command within Vim to represent lines
12 again. These lines may represent the contents of an
if statement, for example, that we would like to indent. We search first for the carat symbol,
^ (the start of a line), and replace it with a tab (
\t). There is no need for the global option as the start of a line obviously only occurs once per line. Using this method, we can quickly add indents to a file as required, and we are again Zen superheroes of Vim.
Now that we are the administrator, the Zen master of search and replace, we can use these skills to tidy configuration files that often have many hundreds of commented lines within them. I do not mind documentation but when it becomes such an overwhelming majority, it can take over. Consider the
httpd.conf Apache configuration file under
/etc/httpd/conf/. This has 675 commented lines. We perhaps want to keep the original file as a reference. So let's first make a copy by executing the following command; we know how to do this from the Preface of this book and if you did not read it, now is your chance to read it before a letter goes home to your parents.
# cd /etc/httpd/conf # cp httpd.conf httpd.conf.$(date +%F)
We can easily list the commented lines using the following command that counts the lines that begin with the
# sign, a comment:
# egrep -c '^#' httpd.conf
On my system, we see that there are 675 such lines. Using sed or Vim, we can remove the comments, firstly, with sed, as follows:
# sed -i '/^#/d' httpd.conf
Then, within Vim with the file open, it is a little different:
The result is the same in both examples where we have reduced the numbers of lines in the file by about two-thirds.
In each chapter, I want to make sure that there has been at least one item of value that you feel you can take away with you and use; how did I do in this chapter? If you recall, we have reviewed a few shortcuts that may help us navigate the command history effectively. Quickly, we moved on to discover the text editor vi or, more commonly now, Vim. For those that need a little help getting started with Vim, we additionally have gVim available to use if we are working on the desktop. Customizing any system is important to make us feel that we own the system and it works for us. With Vim, we can use the
.vimrc file found in our home directory. We were able to add a little bling to Vim with some extra key mapping and desirable options. From then on, it was straight down to work to see what Vim could do, and how the search and replace and delete options that we reviewed worked.