May the source be with you, but remember the KISS principle ;-)
Home Switchboard Unix Administration Red Hat TCP/IP Networks Neoliberalism Toxic Managers
(slightly skeptical) Educational society promoting "Back to basics" movement against IT overcomplexity and  bastardization of classic Unix

Line Ranges in Ex

News Books Recommended Links

Defining a Range of Lines

Ctags Etc

Most ex commands can accept a line range in front of them. By specifying the line range you restrict the command execution to this particular part of text only. Line range consists of one line specifier or two line specifiers, separated with a comma or semicolon. Specifiers can be line numbers, search expressions or bookmarks. In the latter case you need to mark the nessesary positions in the text typing ml , where "l" can be any letter, and use it later defining the line address.

Specifier Description
number an absolute line number
. the current line
$ the last line in the file
% the whole file. The same as 1,$
't position of mark "t"
/pattern[/] the next line where text "pattern" matches.
?pattern[?] the previous line where text "pattern" matches
\/ the next line where the previously used search pattern matches
\? the previous line where the previously used search pattern matches
\& the next line where the previously used substitute pattern matches

If no line range is specified the command will operate on the current line only.

Ranges of lines that can be given to edit commands include:

Absolute line number

6 refers to line 6

1,6 refers to lines 1 to 6

Relative line numbers

-2 refers to 2 lines before the current line

+3 refers to 3 lines after the current line

-2,+3 refers to a range from 2 lines before the current line to 3 lines after the current line

Special symbols

$ refers to the last line in the file e.g. $p to display last line, 1,$p to display entire file

. refers to the current line e.g. .,$p to display from the current line to the end


6d			- deletes lines the sixth line1,6d			- deletes the first six lines1,$d			- deletes all lines3a			- append text after line three.,+10w new	- saves the next ten lines to a file called new

The = operator gives the line number, with the last line the default, so typing = gives you the number of lines in a text. The number of the current line is obtained by typing .=.


Each may be followed (several times) by "+" or "-" and an optional number. This number is added or subtracted from the preceding line number. If the number is omitted, 1 is used.

/\#Step 1/+,/\#Step 2/-

- all lines between Step 1 and Step 2, non-inclusively, i.e. the lines containing Section 1 and Section 2 will not be affected.

The /pattern/ and ?pattern? may be followed by another address separated by a semicolon. A semicolon between two search patterns tells Vim to find the location of the first pattern, then start searching from that location for the second pattern.

/sub scan/;/^\{$/-,/sub log/+

The next example shows how you can reuse you search pattern:

:/lineno/+;+2 y

- this will search for the Section line and yank (copy) one line after into the memory.

:// normal p

- and that will search for the next Section line and put (paste) the saved text on the next line.


     N | Command            | Meaning
     * | h | ^H | <erase>   | <*> chars to the left.
     * | j | <lf> | ^N      | <*> lines downward.
     * | l | <sp>           | <*> chars to the right.
     * | k | ^P             | <*> lines upward.
     * | $                  | To the end of line <*> from the cursor.
     - | ^                  | To the first CHAR of the line.
     * | _                  | To the first CHAR <*> - 1 lines lower.
     * | -                  | To the first CHAR <*> lines higher.
     * | + | <cr>           | To the first CHAR <*> lines lower.
     - | 0                  | To the first char of the line.
     * | |                  | To column <*> (<ht>: only to the endpoint).
     * | f<char>            | <*> <char>s to the right (find).
     * | t<char>            | Till before <*> <char>s to the right.
     * | F<char>            | <*> <char>s to the left.
     * | T<char>            | Till after <*> <char>s to the left.
     * | ;                  | Repeat latest `f'|`t'|`F'|`T' <*> times.
     * | ,                  | Idem in opposite direction.
     * | w                  | <*> words forward.
     * | W                  | <*> WORDS forward.
     * | b                  | <*> words backward.
     * | B                  | <*> WORDS backward.
     * | e                  | To the end of word <*> forward.
     * | E                  | To the end of WORD <*> forward.
     * | G                  | Go to line <*> (default EOF).
     * | H                  | To line <*> from top of the screen (home).
     * | L                  | To line <*> from bottom of the screen (last).
     - | M                  | To the middle line of the screen.
     * | )                  | <*> sentences forward.
     * | (                  | <*> sentences backward.
     * | }                  | <*> paragraphs forward.
     * | {                  | <*> paragraphs backward.
     - | ]]                 | To the next section (default EOF).
     - | [[                 | To the previous section (default begin of file).
     - | `<a-z>             | To the mark.
     - | '<a-z>             | To the first CHAR of the line with the mark.
     - | ``                 | To the cursor position before the latest absolute
                            |   jump (of which are examples `/' and `G').
     - | ''                 | To the first CHAR of the line on which the cursor
                            |   was placed before the latest absolute jump.
     - | /<string>[/]       | To the next occurrence of <string>.
     - | /[/]               | To the next occurrence of the latest search
                            |   item.
     - | ?<string>[?]       | To the previous occurrence of <string>.
     - | ?[?]               | To the previous occurrence of the latest search
                            |   item.
     - | /<string>/+[n]     | To n-th (default 1st) line after next occurrence
                            |   of <string>.
     - | ?<string>?+[n]     | Idem, searching in the opposite direction.
     - | /<string>/-[n]     | To n-th (default 1st) line before next occurrence
                            |   of <string>.
     - | ?<string>?-[n]     | Idem, searching in the opposite direction.
     - | <find>[;<find>]    | Perform successive `/'|`?' actions.  For example,
                            |   /foo/;/bar        - to next `foo', then
                            |                        to next `bar'
                            |   ?foo?-;/bar       - to line before previous
                            |                        `foo', then to next `bar'
     - | :/<string>[/]      | To the next line containing an occurrence of
                            |   <string>.
     - | :/[/]              | To the next line containing an occurrence of
                            |   the latest searched for item.
     - | :?<string>[?]      | To the previous line containing an occurrence
                            |   of <string>.
     - | :?[?]              | To the previous line containing an occurrence
                            |   of the latest searched for item.
     - | :/<string>/+[n]    | To n-th (default 1st) line after next occurrence
                            |   of <string>.
     - | :?<string>?+[n]    | Idem, searching in the opposite direction.
     - | :/<string>/-[n]    | To n-th (default 1st) line before next occurrence
                            |   of <string>.
     - | :?<string>?-[n]    | Idem, searching in the opposite direction.
     - | :<find>[;<find>]   | Perform successive `/'|`?' actions.  Each <find>
                            |   is of the form /<string/[+[n]] or
                            |   ?<string>?[+[n]].
     - | n                  | Repeat latest `/'|`?' (next).
     - | N                  | Idem in opposite direction.
     - | %                  | Find the next bracket and go to its match
                            |   (also with `{'|`}' and `['|`]').
     - | :[x]               | To the line specified by x.
     - | :[x]+[n]           | To n-th (default 1st) line after line specified
                            |   by x.
     - | :[x]-[n]           | To n-th (default 1st) line before line specified
                            |   by x.

Defining a Range of Lines

You can use line numbers to explicitly define a line or range of lines. Addresses that use explicit numbers are called absolute line addresses. For example:



Delete lines 3 through 18.


Move lines 160 through 224 to follow line 23. (Like delete and put in vi.)


Copy lines 23 through 29 and put after line 100. (Like yank and put in vi.)

To make editing with line numbers easier, you can also display all line numbers on the left of the screen. The command:

:set number

or its abbreviation:

:set nu

displays line numbers. The file practice then appears:

1  With a screen editor
  2  you can scroll the page,
  3  move the cursor, delete lines,
  4  insert characters and more

The displayed line numbers are not saved when you write a file, and they do not print if you print the file. Line numbers are displayed either until you quit the vi session or until you disable the set option:

:set nonumber


:set nonu

To temporarily display the line numbers for a set of lines, you can use the # sign. For example:


would display the line numbers from line one to line ten.

You can also use the CTRL-G command to display the current line number. You can thus identify the line numbers corresponding to the start and end of a block of text by moving to the start of the block, typing CTRL-G, then moving to the end of the block and typing CTRL-G again.

Yet another way to identify line numbers is with the ex = command:


Print the total number of lines.



Print the line number of the current line.


:/ pattern/=

Print the line number of the first line that matches pattern.

Line Addressing Symbols

You can also use symbols for line addresses. A dot (.) stands for the current line; $ stands for the last line of the file. % stands for every line in the file; it's the same as the combination 1,$. These symbols can also be combined with absolute line addresses. For example:



Delete from current line to end of file.



Move from line 20 through the current line to the end of the file.



Delete all the lines in a file.


Copy all lines and place them at the end of the file (making a consecutive duplicate).

In addition to an absolute line address, you can specify an address relative to the current line. The symbols + and - work like arithmetic operators. When placed before a number, these symbols add or subtract the value that follows. For example:


Delete from current line through the next 20 lines.



Move lines 226 through the end of the file to two lines above the current line.



Display line numbers from the current line to 20 lines further on in the file.

In fact, you don't need to type the dot (.) when you use + or -, because the current line is the assumed starting position.

Without a number following them, + and - are equivalent to +1 and -1, respectively.[2] Similarly, ++ and -- each extend the range by an additional line, and so on. The + and - can also be used with search patterns, as shown in the next section.

[2] In a relative address, you shouldn't separate the plus or minus symbol from the number that follows it. For example, +10 means "10 lines following," but + 10 means "11 lines following (1 + 10)," which is probably not what you mean (or want).

The number 0 stands for the top of the file (imaginary line 0). 0 is equivalent to 1-, and both allow you to move or copy lines to the very start of a file, before the first line of existing text. For example:



Copy three lines (the line above the cursor through the line below the cursor) and put them at the top of the file.

Search Patterns

Another way that ex can address lines is by using search patterns. For example:

:/ pattern/d

Delete the next line containing pattern.

: /pattern/+d

Delete the line below the next line containing pattern. (You could also use +1 instead of + alone.)

: /pattern1/,/ pattern2/d

Delete from the first line containing pattern1 through the first line containing pattern2.

:.,/ pattern/m23

Take the text from the current line (.) through the first line containing pattern and put it after line 23.

Note that patterns are delimited by a slash both before and after.

If you make deletions by pattern with vi and ex, there is a difference in the way the two editors operate. Suppose your file practice contains the lines:


Keystrokes Results d/while  

The vi delete to pattern command deletes from the cursor up to the word while, but leaves the remainder of both lines. :.,/while/d  

The ex command deletes the entire range of addressed lines; in this case both the current line and the line containing the pattern. All lines are deleted in their entirety.

Redefining the Current Line Position

Sometimes, using a relative line address in a command can give you unexpected results. For example, suppose the cursor is on line 1, and you want to print line 100 plus the five lines below it. If you type:

:100,+5 p

you'll get an error message saying, "First address exceeds second." The reason the command fails is that the second address is calculated relative to the current cursor position (line 1), so your command is really saying this:

:100,6 p

What you need is some way to tell the command to think of line 100 as the "current line," even though the cursor is on line 1.

ex provides such a way. When you use a semicolon instead of a comma, the first line address is recalculated as the current line. For example, the command:

:100;+5 p


prints the desired lines. The +5 is now calculated relative to line 100. A semicolon is useful with search patterns as well as absolute addresses. For example, to print the next line containing pattern, plus the 10 lines that follow it, enter the command:

:/pattern/;+10 p

Global Searches

You already know how to use / (slash) in vi to search for patterns of characters in your files. ex has a global command, g, that lets you search for a pattern and display all lines containing the pattern when it finds them. The command :g! does the opposite of :g. Use :g! (or its synonym :v) to search for all lines that do not contain pattern.

You can use the global command on all lines in the file, or you can use line addresses to limit a global search to specified lines or to a range of lines.

:g/ pattern

Finds (moves to) the last occurrence of pattern in the file.

:g/ pattern/p

Finds and displays all lines in the file containing pattern.

:g!/ pattern/nu

Finds and displays all lines in the file that don't contain pattern; also displays the line number for each line found.

:60,124g/ pattern/p

Finds and displays any lines between lines 60 and 124 containing pattern.

As you might expect, g can also be used for global replacements. We'll talk about that in Chapter 6.

Combining ex Commands

You don't always need to type a colon to begin a new ex command. In ex, the vertical bar (|) is a command separator, allowing you to combine multiple commands from the same ex prompt (in much the same way that a semicolon separates multiple commands at the UNIX shell prompt). When you use the |, keep track of the line addresses you specify. If one command affects the order of lines in the file, the next command does its work using the new line positions. For example:

:1,3d | s/thier/their/

Delete lines 1 through 3 (leaving you now on the top line of the file); then make a substitution on the current line (which was line 4 before you invoked the ex prompt).

:1,5 m 10 | g/pattern/nu

Move lines 1 through 5 after line 10, and then display all lines (with numbers) containing pattern.

Note the use of spaces to make the commands easier to read.

Global Replacement

Sometimes, halfway through a document or at the end of a draft, you may recognize inconsistencies in the way that you refer to certain things. Or, in a manual, some product whose name appears throughout your file is suddenly renamed (marketing!). Often enough it happens that you have to go back and change what you've already written, and you need to make the changes in several places.

The way to make these changes is with a powerful change command called global replacement. With one command you can automatically replace a word (or a string of characters) wherever it occurs in the file.

In a global replacement, the ex editor checks each line of a file for a given pattern of characters. On all lines where the pattern is found, ex replaces the pattern with a new string of characters. For right now, we'll treat the search pattern as if it were a simple string; later in the chapter we'll look at the powerful pattern-matching language known as regular expressions.

Global replacement really uses two ex commands: :g (global) and :s (substitute). Since the syntax of global replacement commands can get fairly complex, let's look at it in stages.

The substitute command has the syntax:


This changes the first occurrence of the pattern old to new on the current line. The / (slash) is the delimiter between the various parts of the command. (The slash is optional when it is the last character on the line.)

A substitute command with the syntax:


changes every occurrence of old to new on the current line, not just the first occurrence. The :s command allows options following the substitution string. The g option in the syntax above stands for global. (The g option affects each pattern on a line; don't confuse it with the :g command, which affects each line of a file.)

By prefixing the :s command with addresses, you can extend its range to more than one line. For example, this line will change every occurrence of old to new from line 50 to line 100:


This command will change every occurrence of old to new within the entire file:


You can also use % instead of 1,$ to specify every line in a file. Thus the last command could also be given like this:


Global replacement is much faster than finding each instance of a string and replacing it individually. Because the command can be used to make many different kinds of changes, and because it is so powerful, we will first illustrate simple replacements and then build up to complex, context-sensitive replacements.




Groupthink : Two Party System as Polyarchy : Corruption of Regulators : Bureaucracies : Understanding Micromanagers and Control Freaks : Toxic Managers :   Harvard Mafia : Diplomatic Communication : Surviving a Bad Performance Review : Insufficient Retirement Funds as Immanent Problem of Neoliberal Regime : PseudoScience : Who Rules America : Neoliberalism  : The Iron Law of Oligarchy : Libertarian Philosophy


War and Peace : Skeptical Finance : John Kenneth Galbraith :Talleyrand : Oscar Wilde : Otto Von Bismarck : Keynes : George Carlin : Skeptics : Propaganda  : SE quotes : Language Design and Programming Quotes : Random IT-related quotesSomerset Maugham : Marcus Aurelius : Kurt Vonnegut : Eric Hoffer : Winston Churchill : Napoleon Bonaparte : Ambrose BierceBernard Shaw : Mark Twain Quotes


Vol 25, No.12 (December, 2013) Rational Fools vs. Efficient Crooks The efficient markets hypothesis : Political Skeptic Bulletin, 2013 : Unemployment Bulletin, 2010 :  Vol 23, No.10 (October, 2011) An observation about corporate security departments : Slightly Skeptical Euromaydan Chronicles, June 2014 : Greenspan legacy bulletin, 2008 : Vol 25, No.10 (October, 2013) Cryptolocker Trojan (Win32/Crilock.A) : Vol 25, No.08 (August, 2013) Cloud providers as intelligence collection hubs : Financial Humor Bulletin, 2010 : Inequality Bulletin, 2009 : Financial Humor Bulletin, 2008 : Copyleft Problems Bulletin, 2004 : Financial Humor Bulletin, 2011 : Energy Bulletin, 2010 : Malware Protection Bulletin, 2010 : Vol 26, No.1 (January, 2013) Object-Oriented Cult : Political Skeptic Bulletin, 2011 : Vol 23, No.11 (November, 2011) Softpanorama classification of sysadmin horror stories : Vol 25, No.05 (May, 2013) Corporate bullshit as a communication method  : Vol 25, No.06 (June, 2013) A Note on the Relationship of Brooks Law and Conway Law


Fifty glorious years (1950-2000): the triumph of the US computer engineering : Donald Knuth : TAoCP and its Influence of Computer Science : Richard Stallman : Linus Torvalds  : Larry Wall  : John K. Ousterhout : CTSS : Multix OS Unix History : Unix shell history : VI editor : History of pipes concept : Solaris : MS DOSProgramming Languages History : PL/1 : Simula 67 : C : History of GCC developmentScripting Languages : Perl history   : OS History : Mail : DNS : SSH : CPU Instruction Sets : SPARC systems 1987-2006 : Norton Commander : Norton Utilities : Norton Ghost : Frontpage history : Malware Defense History : GNU Screen : OSS early history

Classic books:

The Peter Principle : Parkinson Law : 1984 : The Mythical Man-MonthHow to Solve It by George Polya : The Art of Computer Programming : The Elements of Programming Style : The Unix Haterís Handbook : The Jargon file : The True Believer : Programming Pearls : The Good Soldier Svejk : The Power Elite

Most popular humor pages:

Manifest of the Softpanorama IT Slacker Society : Ten Commandments of the IT Slackers Society : Computer Humor Collection : BSD Logo Story : The Cuckoo's Egg : IT Slang : C++ Humor : ARE YOU A BBS ADDICT? : The Perl Purity Test : Object oriented programmers of all nations : Financial Humor : Financial Humor Bulletin, 2008 : Financial Humor Bulletin, 2010 : The Most Comprehensive Collection of Editor-related Humor : Programming Language Humor : Goldman Sachs related humor : Greenspan humor : C Humor : Scripting Humor : Real Programmers Humor : Web Humor : GPL-related Humor : OFM Humor : Politically Incorrect Humor : IDS Humor : "Linux Sucks" Humor : Russian Musical Humor : Best Russian Programmer Humor : Microsoft plans to buy Catholic Church : Richard Stallman Related Humor : Admin Humor : Perl-related Humor : Linus Torvalds Related humor : PseudoScience Related Humor : Networking Humor : Shell Humor : Financial Humor Bulletin, 2011 : Financial Humor Bulletin, 2012 : Financial Humor Bulletin, 2013 : Java Humor : Software Engineering Humor : Sun Solaris Related Humor : Education Humor : IBM Humor : Assembler-related Humor : VIM Humor : Computer Viruses Humor : Bright tomorrow is rescheduled to a day after tomorrow : Classic Computer Humor

The Last but not Least Technology is dominated by two types of people: those who understand what they do not manage and those who manage what they do not understand ~Archibald Putt. Ph.D

Copyright © 1996-2021 by Softpanorama Society. was initially created as a service to the (now defunct) UN Sustainable Development Networking Programme (SDNP) without any remuneration. This document is an industrial compilation designed and created exclusively for educational use and is distributed under the Softpanorama Content License. Original materials copyright belong to respective owners. Quotes are made for educational purposes only in compliance with the fair use doctrine.

FAIR USE NOTICE This site contains copyrighted material the use of which has not always been specifically authorized by the copyright owner. We are making such material available to advance understanding of computer science, IT technology, economic, scientific, and social issues. We believe this constitutes a 'fair use' of any such copyrighted material as provided by section 107 of the US Copyright Law according to which such material can be distributed without profit exclusively for research and educational purposes.

This is a Spartan WHYFF (We Help You For Free) site written by people for whom English is not a native language. Grammar and spelling errors should be expected. The site contain some broken links as it develops like a living tree...

You can use PayPal to to buy a cup of coffee for authors of this site


The statements, views and opinions presented on this web page are those of the author (or referenced source) and are not endorsed by, nor do they necessarily reflect, the opinions of the Softpanorama society. We do not warrant the correctness of the information provided or its fitness for any purpose. The site uses AdSense so you need to be aware of Google privacy policy. You you do not want to be tracked by Google please disable Javascript for this site. This site is perfectly usable without Javascript.

Last modified: March 12, 2019