vi tips and tricks

Martin Wicks (wicksy@wicksy.com), Freelance UNIX consultant, 711 Consultancy Limited



The vi editor has a number of options that determine the look and feel of an editing session. To change any session settings in vi, you use the :set command. To display a list of the options and settings, use the :set all command after pressing the Escape key to enter command mode.
One of the options you can set is number, which turns line numbering on and off

Listing 1. Before line numbering is turned on
#
# Internet host table
#
::1     localhost
127.0.0.1       localhost       loghost
192.168.0.6     centos5
192.168.0.10    appserv
192.168.0.11    webserv
192.168.0.12    test
192.168.0.5     solaris10       # Added by DHCP
~
~
~
:set number

This command instructs vi to display a line number against each record in the file you are currently editing. After putting vi into command mode, you can type :set number and press Enter to turn line numbering on.

Listing 2. Line numbering turned on
1  #
     2  # Internet host table
     3  #
     4  ::1     localhost
     5  127.0.0.1       localhost       loghost
     6  192.168.0.6     centos5
     7  192.168.0.10    appserv
     8  192.168.0.11    webserv
     9  192.168.0.12    test
    10  192.168.0.5     solaris10       # Added by DHCP 
~
~
~
:set number

You can use the :set nonumber command to turn line numbering off. You can also use shorthand versions of this and the:set number command—namely, :set nu and :set nonu.
Having line numbers displayed can be particularly useful when you need to quickly calculate the number of lines you want to process with a vi function. This is especially true when the number of lines is long and may span several screens, or you know the range of lines you want to process but need to find the start and end line numbers that you'll use in the appropriate vi command.
If you want to display line numbers every time you enter a vi session, add the line set number to the .exrc file in your home directory.
When writing code in certain programming languages, indentation is an important part of the style to ensure that the code is more readable. You can set up the vi editor to automatically indent to adhere to a language-specific style when necessary. You use autoindent to turn automatic indenting on or off.

Listing 3. Turning automatic indentation on
#!/bin/ksh
#
#
for file in /etc/*
do
        if [[ -f ${file}  ]] ; then
                 echo "${file} is a file"

~
~
~
~
~
:set autoindent

From this point on, if you use leading spaces or tabs in a line, subsequent new lines will be indented to the same place. With vi in command mode, type :set autoindent, then press Enter to turn on automatic indenting. Set the level of indentation by setting shiftwidth. For example, to set each indentation to four spaces, use :set shiftwidth=4 .

Listing 4. Setting the indentation level
#!/bin/ksh
#
#
for file in /etc/*
do
    if [[ -f ${file}  ]] ; then
        echo "${file} is a file"
    elif [[ -d ${file} ]] ; then
        echo "${file} is a directory"
    fi
done 
~
~
:set shiftwidth=4

While in command mode, you can use the >> command to add a level of indentation to an existing line or the << command to remove a level. Precede these commands with an integer to add or remove an indentation level across multiple lines. For example, with the cursor at the start of line 6 in Listing 4 and after entering command mode, type 5>> to add an indentation level to the next five lines. Listing 5 shows the result.

Listing 5. Indenting a block of lines
#!/bin/ksh
#
#
for file in /etc/*
do
        if [[ -f ${file}  ]] ; then
            echo "${file} is a file"
        elif [[ -d ${file} ]] ; then
            echo "${file} is a directory"
        fi
done 
~
~

You can use the :set noautoindent command to turn automatic indenting off. Shorthand versions of this and the autoindentcommand are also available—namely, :set ai and :set noai. You can also turn indentation on and set the indentation level in one command by using :set ai sw=4.
If you want to enable automatic indentation and set the indentation level to four spaces every time you start a vi session, add the line set ai sw=4 to the .exrc file in your home directory.
As you would expect, pattern matching on searches in UNIX® is case sensitive. However, if you want vi to ignore case sensitivity, you can use the :set ignorecase command. Turn case sensitivity back on using :set noignorecase. You can also use shorthand versions (:set ic and :set noic).
If you want to ignore case sensitivity on searches every time you enter a vi session, you can add the line set ignorecase to the .exrc file in your home directory.
You can search for strings in vi using the / command, specifying the pattern to match either as a literal string or as a regular expression. For example, to search for the word echo in a file, enter command mode, type /echo, and then press Enter. This command would find the first word on line 3 in the file shown in Listing 6.

Listing 6. Compound searches
1  #!/bin/ksh
     2  #
     3  echo "Starting"
     4  file=${1}
     5
     6  echo ${file}
     7
     8  if [[ ${file} = 1 ]] ; then
     9          ((file=${file}+1))
    10          echo "Adding one gives " \
    11                  ${file}
    12  fi
    13  echo "Ending"
    14  exit
~
~

You can use a simple regular expression to specify that you want to find a line containing one word followed by another. For example, to find the first line containing the string echo followed by zero or more characters followed by the string file, you would use /echo.*file. In the file shown in Listing 6, this command would find the first word on line 6.
However, this command will only find matches where both strings exist on the same line. If you want to search for the first occurrence of a pattern or string where it follows another regardless of whether both patterns or strings exist on the same line, you can use a compound search by specifying both search commands separated by a semi-colon (;). For example, to search for the first occurrence of the string echo where it follows the string {file}+1, you would use /{file}+1/;/echo/. In the file shown in Listing 6, this command would find the first word on line 10.
Compound searches are particularly useful when you are searching through code for the existence of a command that specifically follows another—for example, where a function is called after a particular variable is set.
When searching for patterns to replace within a file, you can instruct vi to save any patterns that it matches into a buffer, which can then be replayed in substitutions using a buffer reference number. You do this by enclosing the pattern within \( and \), which instructs vi to save the pattern into a numbered buffer (1 to 9). You can then reference these buffers in substitutions using the buffer references \1 to \9.
For example, to search the file in Listing 7 for lines starting with the word Martin and for each occurrence to add the prefix Mr and the suffix Wicks, enter command mode, type the vi command :%s/^\(Martin\)/Mr \1 Wicks/g, and then press Enter.

Listing 7. Replaying search patterns (before)
Martin is an IT consultant. Martin likes
snowboarding and mountain biking. Martin has
worked on UNIX systems for over 15 years. Martin also
worked for many years before that on mainframes.
Martin lives in London.
~
~
~
~
:%s/^\(Martin\)/Mr \1 Wicks/g

Here's a breakdown of the command into its components:
  • :%s - Instructs vi to perform a substitution.
  • / - Pattern separator.
  • ^\(Martin\) - Look for lines starting with the string Martin, and save the string in buffer 1.
  • / - Pattern separator.
  • Mr \1 Wicks - Substitute the string located with the string Mr, followed by the contents of buffer 1 followed by the stringWicks.
  • / - Pattern separator.
  • g - Global change (that is, change every occurrence on every line matched).
You can use the buffer reference in both the search and in the substitution string.
The resulting changes are shown in Listing 8.

Listing 8. Replaying search patterns (after)
Mr Martin Wicks is an IT consultant. Martin likes
snowboarding and mountain biking. Martin has
worked on UNIX systems for over 15 years. Martin also
worked for many years before that on mainframes.
Mr Martin Wicks lives in London.
~
~
~
~
:%s/^\(Martin\)/Mr \1 Wicks/g



You can tell vi to place a bookmark at a point in a file by pressing the Escape key followed by the M key followed by another alphabetic character that denotes the bookmark reference. Therefore, you have up to 26 bookmarks named a to z. To return to the previous bookmark, press the Escape key followed by the back tick (`) followed by the bookmark reference alphabetic character.
For example, after pressing Escape followed by the MA keys, you would save the current cursor position into a bookmark nameda. Whenever you want to return to that cursor position later in the editing session, you simply press Escape followed by the `Akeys. To flip between the current bookmark and the previous one, you can use the double back tick (``) command sequence.
One of the most useful Search/Replace features of the vi editor is the ability to find a string matching a pattern, update it, and then repeat the same search for the next occurrence and optionally repeat the update against it, much like the Find Next/Replace functions found in Microsoft® Word.
You probably already know that you can search for string patterns in vi by entering command mode, typing /search_pattern(where search_pattern is a string or regular expression), and then pressing Enter. Doing so takes you to the first occurrence of a string matching the pattern specified. From here, you can perform whatever operation you want on the located text. For example, pressing Escape followed by the C and W keys followed by more text changes the located string to another word.
To quickly locate the next occurrence of a matching pattern, you press Escape followed by the N key. When the next match is found, you can optionally use the period key (.) to repeat the last text operation at this location, such as the change word (cw) function used in the previous example. You can then continue to find further matches (n) and optionally repeat the text operation (.) using these keys in much the same way you would use the Find Next and Replace functions in Word.
You can switch the case of the alpha character underneath your cursor in vi by pressing Escape, and then pressing the tilde key (~). Doing so shifts from lowercase to uppercase and vice versa. Holding down the key rolls over each character in the line, flipping the case of any alpha characters the editor comes across. You can enter a numeric character prior to the tilde to denote how many alpha characters you want to change.
You probably know that you can execute commands in a shell within vi by pressing Escape, typing :!command, where commandis the UNIX command that you want to execute—for example, :!pwd to show the present working directory your editing session is in—and then pressing Enter.
However, you can also send a section of your file as the standard input to a UNIX command of your choice and have the same section in your editing buffer replaced by the resulting output. For example, if you wanted to sort the entire file shown in Listing 9 while remaining in the vi session, you would press Escape, type :1,$!sort to instruct vi to pass lines 1 through the end of the file ($) into the sort command, replacing the specified section with the output, and then press Enter.

Listing 9. Sorting a file inside the vi session (before sort)
5
4
3
2
7
6
5
4
8
9
6
3
1
3
4
~
~
:1,$!sort

Listing 10 shows the resulting output from the sort operation.

Listing 10. Sorting a file inside the vi session (after sort)
1
2
3
3
3
4
4
4
5
5
6
6
7
8
9
~
~
:1,$!sort

Alternatively, you can prefix the shell command with the number of lines you want it to operate on from the current cursor. To do so, press Escape, then type a numeric character specifying the number of lines followed by double exclamation marks (!!) followed by the UNIX command.
For example, with the cursor at the start of line 4 in Listing 9, you would press Escape, then type,
4!!awk '{print "New text",$0}'

and press Enter to prefix lines 4 through 7 inclusive with the text New text, as shown in Listing 11.

Listing 11. Prefixing a block of lines with new text
5
4
3
New text 2
New text 7
New text 6
New text 5
4
8
9
6
3
1
3
4
~
~
!awk '{print "New text",$0}'

You can string UNIX commands together using the pipe separator (|) to create complex and powerful filtering within your vi session. For example, to replace the contents of the file in the editing buffer of your current vi session with the first white space-delimited field of each line, sorted into ascending order and translated to uppercase, you would enter the following line after pressing Escape:
:1,$!awk '{print $1}' | sort | tr [:lower:] [:upper:]

You can save sections of a file you're currently editing by pressing Escape, and then entering :start,endfile, where start is the first line in the current file from which you want to save, end is the last line that you want to save to, w denotes that you want to write to another file (or overwrite an existing file), and file is the name of the file to which you want to save the specified section. You can use the $ notation for the last line to specify to the end of the file and double greater-than symbols (>>) after the w to indicate that you want to append to rather than overwrite the file. The example in Listing 12 shows lines 6 to 9, inclusive, being appended to a file called /tmp/newfile.

Listing 12. Saving a section of a file to another, appending rather than overwriting it 
1  #
     2  # Internet host table
     3  #
     4  ::1     localhost
     5  127.0.0.1       localhost       loghost
     6  192.168.0.6     centos5
     7  192.168.0.10    appserv
     8  192.168.0.11    webserv
     9  192.168.0.12    test
    10  192.168.0.5     solaris10       # Added by DHCP 
~
~
~
:6,9w >> /tmp/newfile

The vi editor is an extremely powerful tool, and this article provides you with a number of tips and tricks that will hopefully make your file editing more efficient. Remember, there's always more to vi that meets the eye. Happy editing!
vi tips and tricks vi tips and tricks Reviewed by Unknown on quinta-feira, agosto 12, 2010 Rating: 5

Nenhum comentário