$ ed filename   # open the file 'filename'

the contents of the file are copied to a buffer; if no file is provided, the buffer is empty. changes are always applied to the buffer. if changes are not saved, they are lost when closing the editor.

there are several versions of ed, with slightly different arguments and commands; the -G argument runs gnu’s ed in compatibility mode.

interacting with ed is similar to interacting with a shell. a prompt is displayed while it reads lines from standar input. if the input doesn’t match with a command, an error is returned.

the default prompt is an empty string, but it can be changed using the -p option:

$ ed -p-  # use '-' as the prompt 

addresses

the user enters commands in the standard input. most commands consist of only one line and are of the form:

    [address[,address]]command[parameters]

the commands are applied to the lines given by the addresses. an address can be:

    1p  prints the first line of the buffer
    0p  error: 0 can't be printed
    1,4p    print lines 1 through 4
    2   set current 2 as the current line
    # '-' is not the prompt, there is no prompt
    -0p print the last line
    -1p print the second-to-last
    .p  print the current line
    .   print the current line
    .,3p    print the lines between the current address and the third line
    d   delete the line in the current address
    0p  error: 0 can't be printed
    0a  add text at the beggining of the buffer (the previous first line will be the second line.
    1,$p    print the entire file
    1,$d    erase the content in the buffer

two addresses separatad by a comma represent the range of lines between them, with both ends included:

    1,2 first and second lines
    1,$ all lines in the buffer

the second address has to be bigger than the first:

    3,1 error: 3 > 1
    1,1 first line
    .,3 lines between the current address and the third line.
        if '.' is bigger than 3, then the address is invalid
    .n  # print the current line and its number
    3   # current address is 3
    +2  # advance the current address two places
    5   # now current address is 5
    -2  # go back two places
    3   # now current address is 3
    -   # equivalent to -1
    2   # now current address is 2
    +   # equivalent to +1
    3   # now current address is 3

. /re/ search the line for a match to the regular expression re. the search starts with the inmediate address after ., and wraps to the first line if it reaches the end of the buffer. if a match is found, the current address is set to the matched line.

    a       # adding some lines to show /re/ working
    uno
    dos
    tres
    cuatro      # the name of the line equals its address
    .
    2
    dos     # '.' is set to 2
    /atr/       # search for a line with the string 'atr'
    cuatro      # the 4th line contains 'atr'
    .n      # print current address along with the line address
    4   cuatro  # '.' was set to 4, the matching line
    
    /o/     # now search using /o/
            # the search reaches the end and wraps
            # to the first line
    uno     # the line 'uno' matches /o/
    .n      # print current address
    1   uno # current address is set to 1

/re/ matches the first line it finds and stops so, in the example above, the search stoped at line 1 even though line 2 (dos) also matches the pattern.

    a       # adding some lines to show ?re? working
    uno
    dos
    tres
    cuatro      # the name of the line equals its address
    .
    2
    dos         # '.' is set to 2
    ?atr?       # search for a line with the string 'atr'
    cuatro      # the 4th line contains 'atr'
    .n          # print current address along with the line address
    4   cuatro  # '.' was set to 4, the matching line
    ?o?     # search backwards for the pattern 'o'
    dos     # second line matches the pattern
    .n
    2   dos # now the matched line is the 2nd,
            # because the search started at the 4th line
            # and proceeded backwards
    a       # adding some lines to show ?re? working
    uno
    dos
    tres
    cuatro      # the name of the line equals its address
    .
    2
    dos     # '.' is set to 2
    ka      # mark line 2 using a as a key
    'an     # print line and address of the line marked as 'a'
    2   dos # the line with key a is the second
            # one, so '.' is set to 2
    'ad     # delete the line marked with a
    ,p      # print file to show the line was deleted
    uno
    dos
    tres

commands

commands cause ed to perform an action upon one or more lines. if the user enters (at the prompt) an address followed by a letter matching a command, then the commands is executed on the addressed lines. most commands have a default line to use if no address is provided.

    $ cat file
    first line
    second line
    $ ed -G -p- file
    39
    -,p     # ',' is the entire file, and 'p' is the print command
            # it prints the lines especified by the address
    first line
    second line
    -,n     # print the lines and the line numbers
    1   first line
    2   second line

in the list of commands below default lines are between (); for example (.)p means that the command p applies to the current line if no address is specified. also, the prompt is set to -, when there is one, and the shell prompt is $.

    -,p
    line 1
    line 2
    line 4
    -.p
    line 4
    -a      # add lines belw 3
            # a accepts lines from stdin
            # and adds them after the line in the address
            # a '.' in a line by itself comes back to the prompt
    line 5
    line 6
    -.n     # print current address
            # the current address is set to the last line entered
    5   line 6
    -,p     # print entire file
    line 1
    line 2
    line 4
    line 5
    line 6
    -2a     # add lines after '2'
    line 2
    'a' accepts more than one line
    .
    -,n
    1   line 1
    2   line 2
    3   line 3
    4   'a' accepts more than one line
    5   line 4
    6   line 5
    -,p     # print all lines in the file
    first line
    second line
    third line
    fourth line
    -1d     # delete first line
    -,p
    second line
    third line
    fourth line
    -3d     # delete line number 3
    -.p     # print current address
    third line  # the current address is one above the deleted range
            # because there is no line after it
    -,p
    second line
    third line
    -,p
    uno
    dos
    tres
    -2
    dos
    -j  # join the default lines:
    -p  # the current address and the next (.,+)
    uno
    dostres # lines 2 and 3 were replaced by the line
        # resulting of the join of line 2 and 3
    -,p
    año
    -,l
    a\303\261o

an unscaped & in replacement is changed to the current match. if replacement is % the one from the last substitution is used. for replacement to contain a newline, it must be scaped with \.

    -,n
    1   bla bla bla match match match bla
    2   bla bla bla match match match bla
    3   bla bla bla match match match bla
    4   bla bla bla match match match bla
    5   bla bla bla match match match bla
    -1,2s/match/changed/
    -,n
    1   bla bla bla changed match match bla
    2   bla bla bla changed match match bla
    3   bla bla bla match match match bla
    4   bla bla bla match match match bla
    5   bla bla bla match match match bla
    -3,4s/match/changed/g
    -,n
    1       bla bla bla changed match match bla
    2       bla bla bla changed match match bla
    3       bla bla bla changed changed changed bla
    4       bla bla bla changed changed changed bla
    5       bla bla bla match match match bla
    -5s/match/changed/3
    -,n
    1       bla bla bla changed match match bla
    2       bla bla bla changed match match bla
    3       bla bla bla changed changed changed bla
    4       bla bla bla changed changed changed bla
    5       bla bla bla match match match bla
    -,n
    1   bla bla bla match match match bla
    2   bla bla bla match match match bla
    3   bla bla bla match match match bla
    4   bla bla bla match match match bla
    5   bla bla bla match match match bla
    -2,4s/match/changed/3
    -,n
    1   bla bla bla match match match bla
    2   bla bla bla match match changed bla
    3   bla bla bla match match changed bla
    4   bla bla bla match match changed bla
    5   bla bla bla match match match bla
    -1s     # repeat last substitution on line 1
    -,n
    1   bla bla bla match match changed bla
    2   bla bla bla match match changed bla
    3   bla bla bla match match changed bla
    4   bla bla bla match match changed bla
    5   bla bla bla match match match bla
    -5sg    # on line 5 repeat the last substitution but
            # toogle the global flag: last one didn't have
            # the global flag so this time it will
    -,n
    1   bla bla bla match match changed bla
    2   bla bla bla match match changed bla
    3   bla bla bla match match changed bla
    4   bla bla bla match match changed bla
    5   bla bla bla changed changed changed bla
    -,n
    1   line 1
    2   line 2
    3   line 3
    4   line 4
    -2,3t0
    -,n
    1   line 2
    2   line 3
    3   line 1
    4   line 2
    5   line 3
    6   line 4
    ,n
    1   a uno
    2   b dos
    3   c tres
    4   d uno
    5   e dos
    6   f dos
    7   g tres
    g/dos/.n\
    d\
    .n
            # first match (b dos)
    2   b dos   # .n prints the current line
            # d deletes current line
    2   c tres  # .n prints current line (2)
            # --------------------------
            # second match (e dos)
    4   e dos   # .n: 'e dos' is now line 4
            # d deletes line 4: e dos
            # .n prints line 4: f dos
            # --------------------------
            # third match (f dos)
    4   f dos   # .n: 'f dos' is now line 4
            # d deletes line 4: f dos
    4   g tres  # .n prints line 4: g tres
            # no more matches
    ,p
    match 1
    pass
    pass
    match 2
    pass
    match 3
    pass
    G/match/
    match 1    # match found, printed line, set as current address
    d          # delete the line
    match 2    # match found
    a\         # add a line below the match
    newline    # \ used for multiline command list and arguments
    match 3
    .c\        # replace matching line
    changed
    ,n
    pass
    pass
    match 2
    newline
    pass
    changed
    pass
    $ ls
    $ ed -G -p- ~/some/existing/file
    -,p
    line 1
    line 2
    line 3
    .
    -w
    21
    -1,2w test
    14
    $ cat test
    line 1
    line 2
    -,p
    how many words?
    -w !wc -w
    3       # the result of echo "how many words?" | wc -w
    16      # number of characters passed to the command
    -a
    now how many?
    what about now?
    .
    -,p
    how many words?
    now how many?
    what about now?
    -2,3w !wc -w
    6
    30
    $ ls
    $ ed -G -p-
    -a
    line1
    line2
    .
    -,W test
    12
    -q
    $ ls
    test
    $ cat test
    line1
    line2
    $ ed -G -p-
    -a
    W appends at the end of the file
    it does not overwrites it
    .
    -,W test
    59
    -q
    $ cat test
    line1
    line2
    W appends at the end of the file
    it does not overwrites it
    $ ed -G -p-
    -a
    it's also possible to append
    some lines, not just the entire file
    for example, the first and last lines of this buffer
    won't be appended
    .
    - 2,3W test
    137
    -q
    $ cat test
    line1
    line2
    W appends at the end of the file
    it does not overwrites it
    some lines, not just the entire file
    for example, the first and last line
    -z10    # prints 10 lines starting whith the current address
    -z10n   # prints the same but it adds the line numbers
    -10z20  # prints 20 lines from line number 10 (included)
    -10z    # prints an entire window of lines from 10

the command z is useful for scrolling: repeated z commands prints succesive windows, effectivly navigating the buffer one screen at a time (which is called scrolling).

    -,n # print line and line number
    1   one
    2   two
    3   three
    -1n
    1   one
    -+
    two
    -+
    three
    -1n
    1   one
    -++ # cumulative effect
    three   # advanced two lines fordward
    1
    one
    -
    two # a line by itself is equivalent to +
    -
    three
    $ ls
    file1
    file2
    $ ed -G -p-
    -r !ls
    14
    -,p
    file1
    file2
    -0r !ls
    14
    file1
    file2
    file1
    file2
    $ ls
    file1
    file2
    $ ed -G -p-
    -!ls
    file1
    file2
    !
    -!!
    ls
    file1
    file2
    !

using ed

good properties:

references