Ed
From blag.wiki.aktivix.org
Contents |
INTRO
man ed | col -b produces the text for the man command. This is a commentary on the man page. I should go for man bash, but i'm avoiding it. (please help out by correcting -any- mistakes and completing the commands highlighted as (TODO).
ed is the father of ex, which begat vi, which begat vim. use it. Need it. Want it. Live it. It's a good editor to use if you want to get to know regular expressions, which are used by ed, vi, grep and so on.
You start in command mode. If a file name is given to ed when it is invoked at the command line then a copy of that file is put into the "buffer" and this is what you edit. So when you start to work on a file you actually are editing the buffer and not the original file. Changes are saved if and only if the save command is given.
Command mode allows you modify the text with single-letter commands combined with regular expressions. This is useful to change the text without actually needing to manually find string and changing them.
CHANGING TEXT
The single-letter commands:-
a - append
c - change
i - insert
are typical of the command format, (or syntax??),of this editor. The three commands shown above are sent to the editor to allow the user to enter into "insert mode", which allows him to start typing stuff into the buffer. Remember that it is the buffer that is edited and not the original file. When the user is in "insert mode" no single-letter commands are avialable as the buffer is being modified directly. Everything typed from hereon is text for the buffer.
STOPPING INSERT MODE
All forms of insert commands, (like the single-letter a,i,c shown above), can be stopped with a single dot "." Entered on a line followed by a carriage return.
MORE COMMANDS
All commands apply to sinlge lines or a collection of lines:-
m - move line(s)
d - delete line(s)
s - substitute
n - number line(s)
l - list line, shows additional characters like those showing end of line this
command can be used to change sections of lines, i.e single words or characters
within a single line or range of lines.
THE ED COMMAND
A typical ed command follows this strucuture:-
address1,address2 command parameters
The addresses are optional as one can have one or more of them. There are a number of ways to refer to lines of text. (more of that later). The command is what the editor should do with the line(s) if there are any and there are a few additional parameters that you can give to the ed command. I find the most usefull one follows this syntax:-
ed -p "-> " path/to/filename.foo
Normally ed does not give you a prompt. A promptless editor may take some getting used to. This gives you a simple prompt that looks like this:-
->
so you can start giving ed some commands. Arguments of the type
ed filename
and
ed !filename
specify a file who's contents will be copied to the buffer. The latter command format tells the editor that there are commands to follow. i.e., it is to be treated as a shell script. Note that the exclamation mark (!) may need to be escaped in some shells.
LINE ADDRESSING
All of the lines of text within a file's buffer (remember that we edit the buffer and not the original file), are given a line number. The line numbers are unique. Where am I in this file? What line am I at now? A newly opened file has the current line as the very last line of the buffer. Think of ed reading all of the text and ending up as the the very last line of the file. To see what line number you are at within a buffer, issue the single letter commands:-
p to print the line
n to number the line
l to print the line with any special characters like tabs and so on
Commands are always applied to the current buffer line address unless otherwise specified by you. There are a number of ways to call buffer adress lines:-
. The current line in the buffer
- previous line
+ following line
examples of off-sets are:-
-2 the two lines up within the text
+6 lines lines forward
etc
Note that the ed editor reads these addresses from l-r
RANGES
example syntax:-
20,40p
will print all lines from 20 to 40 inclusive
,$
all lines in the buffer from first to last inclusive. This is the same as "1,$" in the example below.
1,$
a range specifying all lines in the buffer. from 1st to last line in the buffer. This is exactly the same as the ",$" example given above,
$
the last line in the buffer
%
same as "," in other words, refers to all of the lines in the buffer
.
Is the current line
;
from the current to last line in other words the same as .,$
/re/
as in regular expression. Search from current line "." to first occourence of re. Search will jump to wherever term is found.
//$
repeat the last search
?re?$
a backward search. This search is performed backwards through the text
??
repeats last search, but do it backwards
'[single lower case char]
a line mared with a `k` command, which is used to mark a line for later commands
REG EXPS
Regular expressions. These are only usefull if they are used alot. They will always seem hard at first. Just aquire the right habits and they will become very usefull. Use them to find words and patterns in individual lines or ranges of lines. Can be combined with commands to change the pattern(s). Remember that the most basic reg exps are:-
/re/
for searching forwards and
?re?
for searching backwards
Where re is a regular expression, character(s) or string(s) that you are trying to find within the text.
//
and
??
are use for repeating the last regular expression search. Saves you typing out the command again
g//
can be used to find all (global) occourences of the last search
g??
also works too, repeats last search, but do it backwards
g//n
print all cases of the last forward search
g??d
delete all cases of the last backward search
g/re/p
prints all matched expressions
g/re/n
number lines the above
g/re/new/s
changes all occourences of re to new
g/re/d
deletes all lines containing re
BACKSLASHING OR CHARACTER "escaping" (TODO)
Use to escape the normal meaning of special characters. Just experiment to know what they are for now.
CHARACTER CLASSES
They seem a bit confusing at first glance when you read the man page. You'd think that something like
g/^[:space:]/would search for "a character class called space". Well it doesn't. The man page lists a number of classess in the [:foo:] format. To use/search for a class use
[[:foo:]], where foo is the name of the class. Lets's try this out.
dmesg > hahaha.txt
Now we will work with the file "hahaha.txt" and see how these character classes work.
ed hahaha.txt
If you want a prompt use
ed -p "$ " hahaha.txt
Let's look for some characters
g/^[:space:]/p
This command says "print all of the lines that begin with..... You should see that the lines found began with one of the characters s,p,a,c,e,:
Let's look for a character class
g/^[[:space:]]/p
This command says "print all of the lines that begin with a space"
g/^[[:upper:]]/p
This command says "print all of the lines that begin with an upper case character"
To quit editing "hahaha.txt" just press q, unless you want to experiment futher with this editor.
More on character classes
/[a-z]/
we search for lowercase letters from the range shown
/[A-Z]/
we search for uppercase letters from the range shown
/[aeiou]/
we search for a vowel
^[foo]
search for line starting with "foo"
$
use to find the last char or string at the end of a line
ex: /lab$/
means: aforward search for a line ending with lab
\(re\)
a subexpression of a search. They can be nested in that you can but searches within searches. a few examples:- (TODO)
$
\(sub)\ (TODO)
tbh these subexpressions have not been mastered/understood yet (TODO)
/.\{40\}/
this is in the form \{n\} which searches for a string or pattern exactly n times or
\{n,\}
exactly n times
\{n,m\}
between n and m times note that this works only when looking for a sinlge character, which can also be a metachar like + . * and so on.
\*
ah, the famous wildcard. Search for a string containing a letter followed by any nunmber of characters.
\<X
we use this to search for a word that starts with a character X, where X is any character
/\<b/n
forward searches for a word starting with b and shows the line and its line number
/Y\>/
search for a word that ends with a character X, x is any character
MORE ESCAPE CHARACTERS
use the \ char to escape special characters shown in the following below:-
/\//
search for a / in a line
/g\//
search for a / in a line
/X\'/
searches for a line ending in charater X
g/X\'/n
searches for a line ending in charater X (TOODO)
/X\?/
/a[bd]\?c/
matches ‘abc’, ‘adc' and ‘ac’
X\+
find the character X one or more times on a line
\b
find the string starting of a word
g/\bide/n
looks for words starting with ide
\bfoo\
for example
g/\bide\b/n
looks for words starting and ending with ide
\w
Matches any character in a word
g/\wdd/n
looks for words containing "dd"
\W
Matches any character @not@ in a word
MORE ON COMMANDS
I think we have repeated this enought that we issuse sinlge-letter commands to the editor. Commands can span over several lines so long as each line but the last one ends with a backslash. Like this;
commands can span over several lines so \
long as each line but the \
last one ends with a backslash
Generally the editor expects only one command per line, but this can be extended by issing one of the following
p to print the line
n to number the line
l to print the line with any special characters like tabs and so on
Use <ctrl> C, (also shown as ^C in man pages), to stop some command that you have issued. For example, printing a file with 600+ lines can be stopped with <ctrl< C.
a
Adds text to the current line in the buffer, where ever that is.
When a file is first opened by ed, the last line becmes the currwnt one. Give ed the single letter command and it puts you into inset mode.
(address1,address2)c
changes the lines given by the range shown on brackets you don't actually use brackets in the address system. These lines are deleted frm the buffer and you are now expected to inster text that will replace these lines
1,4c
will delete lines 1-4. What ever you type from here on will replace those lines. Remembe that you can also give single line addresses. (refer to the section on line addressing above for a recap).
(address1,address2)d
removes the lines given by the range shown on brackets.
e filename (TODO)
filename is a new buffer to be edited. This new buffer is created and you can start working on it. [what happend ro the old file that you where working on?]
e !command (TODO)
use to give commands to the editor. dunno how or what for though :/
E file (Todo)
f file (Todo)
1,$/re/command-list
g/re/command-list
Apply commands to an address range(s) that match the regular expression re. Note that the addys shown here refer to all of the lines within the buffer. You can specify any valid single line addy or a range spanning over a number of lines. (TODO) commands - a bit confusing. No examples given
(1,$)G/re/
gives some commands interactively to the matched addy(ies). Use a single & to repeat the last command.
h
show the last error made
addressi
use to insert text before the line specified
address1,address2j
joins lines together
example: 1,2j
joins the first and second lines of text together
addressklc
the line addy is marked with a single lowr case letter (lc) which can then be erfered to as 'lc. A kind of "short cut" address method.
address1,address2l
prints the line(s) specified showing any non-pritable characters line new lines and tabs. The text will be scrolled screen by screen or line by line, depending on your monitor or termninal
address1,address2maddress3
moves the line(s) specified to another destination
addy1,addy2n
prints the line(s) and the line number(s) of the address(es) specified
addy1,addy2p
prints the line(s) of the address(es) specified
P
toggles the prompt on or off, depending if it was specified with a -p "foo" argument when the editor was invoked. Remember ed is a silent editor that does not give you a prompt unluess specified.
q
quit ed. Note that if you see a single "?" returned then ed is telling you that there are changes to the buffer which will be lost if the file is not saved
Q
quit ed and do not save any changes to buffers
($)r !command (TODO)
SUBSTISTUTIONS
address1,address2,s/old/new/ - type 1
address1,address,s/old/new/g - type 2
address1,address2,s/old/new/n - type 3
replaces the line(s) containing the regular expression old with the string "new". Note that there are three formats of this command:-
type 1 -
executes the replacement (substituion) where the first instance of the regular expressoin "old" is found. All of the other ones, (if there are any), are left unchanged.
type 2 -
executes the replacement (substituion) where all instances of the regular expressoin "old" are found. This affects all instances of the regular expression "old" and they are replaced with "new".
type 3 -
executes the replacement (substituion) where the n'th instance of the regular expressoin "old" is found. This affects only the n'th instance of the regular expression "old" will be replaced with "new".
Note with replacements. A few examples of replacements are shown;
\t insert a tab
\r instet a new line ??????
addy1,addys
repeasts the last subistution exucuted at the addy(ies) specied. It can be combined with any one of the following
addy1,addysx
for the x'th occourence ???
address1,addressr
to issue a command
address1,addressg
for "global", where the command is executed at all occouences found
address1,address
address1,address2taddress3
copies the line(s) to wherever specified
u
undo the last command
address1,address2,v,re,command
apply commnd to line(s) that do not match the regular expression
address1,address2,V
as above but the editor allows you to edit each line interactively
address1,address2,w filename
Writes the addressed line(s) to filename. Take care as th enew contents are writen without warning!
address1,address2,wq filename
as above but writes the file and quits the editor.
address1,address2w !command
Writes the addressed lines to the standard input of ‘!command’. The default filename and current address are unchanged.
address1,addressW filename
Writes the addressed line(s) to filename. The previous contants of filename are preserved.
addressx
copies (puts) the contents of the cut buffer to after the addressed line.
addressy
Copies (yanks) the addressed lines to the cut buffer.
!command
Executes command via sh, (a shell) (TODO)
address=
Prints the line number of the addressed line
z
printts the contents of the buffer a screen at a time
addy+x
prints the contents of the buffer x lines at a time starting from address x