i - insert line[s] of text. This is always used with at least one backslash.
'1 i\ A theory of sed as a brain melting device'
To add multiple lines, follow all lines except the last one with \. Make sure there is nothing after the \.
'1 i\ A theory of sed as a brain melting device\ By someone who has been there.'
Inserted text are sent directly to standard out even if the -n option is in effect. You cannot edit an inserted line with the sed that performed the insert. If you need to edit an inserted line, pipe the output of sed to a second sed to make the changes.
In most case, you will use a specific address to determine the insert location. The insert will occur on the specified line with the actual line moving down the output by the appropriate amount.
The following double spaces (adds an empty line before) every line in the file.
sed -e 'i\
' /home/lx/berezin/Data/regex | less
a - append line[s] of text. Append works the same except it will add the new
lines to output after the current line.
Run man on w3m in preparation for the following. w3m is a simple text web browser. ? will get you help, q will quit, and j is [down] and k [up].
man -S7 regex | ul -t dumb | sed -e '1 i\ <html>\ <body>' -e 's/$/<br>/' \ -e 's/^[ ][ ]*$/<p>/' -e '$ a\ </body>\ </html>' | w3m -T text/html
The preceding adds the following html markups. Inserts the openning html markups, puts the line break at the end of each line, puts paragraph break on any blank lines, and closes the document with the closing html. This is a very basic converter script.
c - change line[s] of text. Change also works similarly. Change will remove the
line or lines specified and replace them in output with the specified lines.
The number of lines removed or "changed" and the number of lines added are
independent of each other.
d - delete line[s] of text. Delete addressed line[s] of text. It is important
to understand that if you delete the line in the pattern space, sed will
fetch a new line from the text file and return to the top of the edit command
list.
In the following example, we try to use delete and insert to imitate change.
man -S7 regex | ul -t dumb | sed -e '1 { #delete the 1st line d # insert a new line in its place. i\ A text version of the REGEX man page Section 7 }' | less
However, the new title line will never be added because after the delete is executed, there is no line to apply edits to and sed moves on to the next line in the file.
To do the above trick without using change, use substitute instead :
man -S7 regex | ul -t dumb | sed -e '1 { # Clear the current line from the pattern space. s/^.*$// # Insert new first line in the output stream. i\ A text version of the REGEX man page Section 7 }' | less
r "filename" - read in a file. Read will read the specified file and redirect
it to the output stream after the current line addressed. Read always appends.
If you need to insert at the beginning of the work text, use the cat
command rather than read. Use read when you need to insert a file in the middle
of the text file.
The following reads in mytable.txt in each location where TEMPLATE&nbs;TABLE appears on a line by itself. It then deletes the line that triggered the read.
# Make sure that you don't accidentally log out IGNOREEOF=10 sed -e '/^TEMPLATE$/ { # read the new block of text into the output stream from the keyboard # Enter a few lines of text. Then, you must enter [ctrl]d twice in a row # to close the input. r /dev/tty # Delete the template line d }' /home/lx/berezin/Data/doc.html > newdoc.html
Use less and then w3m to view newdoc.html
Although it was indicated that sed is non-interactive, because of the way Unix works with files, some unusual tricks can be performed. By indicating the standard terminal interface is the file to read in, we can enter text from the prompt. Remember that r, read, is like insert and anything entered goes directly to the standard out bypassing any other edits specified.
p - print line[s] to output. We have seen the p as a flag for substitute. It
may be used by itself or with just an address or range.
The following acts like a grep that prints out only the lines that contain the html for tables found in the document.
sed -n -e '/<table/,/<\/table/ p' /home/lx/berezin/ph/index.html | less
Remember, if -n not used, print will cause duplicate lines in output.
w "filename" - write line[s] to specified file. Similar to the print except
lines sent to specified file. A file name may be referenced by several edit
commands and, if acted on, data is appended to the file. If the sed command is
re-executed, the previous copy of the written file will be overwritten.
You may find that some versions of sed allow only 7 files to be opened at any time during sed's execution. The GNU versions does not seem to have that limitation.
y - transform line[s], like tr. Use transform to transform each matching
character in the pattern space.
sed -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/' data > cdata
y does not recognize the character class syntax, such as [:lower:], so you need to specify every character. The two lists must be the same length, and the transform is applied to the whole line.
n - next line. The next line command causes sed to move the current line
in the pattern space to standard out and fetch the next line of text to edit
from its file. If there are additional edit commands to apply in the command
list, these are applied to the new line.
The next is useful when lines are paired up. Lets say you have a text database of users where each user record consists of two lines, 1st line is the user login id, and the 2nd line is her/his home directory. We wish to change part of the directory path if the 1st line of the record holds a z-id.
berezin /home/max/berezin z912730 /export/home/lx/z912730 z987654 /export/home/lx/z987654 z123456 /export/home/lx/z123456 |
sed -e '# Make sure the id is the only thing on the line and it is a zid /^z[0-9]\{6\}$/ { #If matched, output and fetch the next line, the path n # change the location of the home directory to same except as with upper case. s#/z\([0-9]\{6\}\)$#/Z\1# }' /home/lx/berezin/Data/db | less
As long as the two lines are properly paired, spacing between records is unimportant.
N - append Next line. The append Next line command fetches the next line of
text but does not output and purge the current line from the pattern buffer.
The new-line between the two lines also stays in the pattern buffer. If N
cannot fetch another line (end of file), the command execution will terminate
even if there are other commands queued up.
The append Next can be used to concatenate lines together. The following will remove double spacing. If paragraphs have two or more blank lines between them, at lease one will be preserved.
A word on multi-edit sed with embedded comments on the command line, bash is very forgiving of this style of command entry. If you find you need to work in a different shell, you may want to keep all your edits in a file and use sed -f to fetch them.
D - delete up to the 1st new-line in pattern space. This is often used in
combination with N.
In the following line data has several lines that may have one or more blank lines between text lines. This removes all but one blank line.
# The 1st edit makes sure line is empty and not just blank. Easier to code the # second edit. sed -e 's/^[[:space:]]*$//' -e '/^$' | sed -e '/^$/{ # If line not empty, don't edit, just output. # If a empty line, encountered, merge it with the next line. N # If both lines empty, only new-line in pattern space, # Then delete 1st line from pattern space. /^\n$/D #If both lines were not empty, no edit occurs and lines output normally }' /home/lx/berezin/Data/linedata | less
If you run the sed to remove spaces between lines in a paragraph and then the sed to remove multiple lines between paragraphs, you can produce a document with single spaced paragraphs with single blank lines between paragraphs.
P - prints pattern space up to the 1st new-line. Often used with N, this
allows the user to fetch the next line into the pattern space and test its
contents to determine the action in the current line.
b - branch. sed supports an internal loop structure. With it you can
bypass or repeat certain edits. A branch has two part, a label or target and
the branch command with the designated label target. Branches can be designed
to be conditional or unconditional, although it is almost always in some form
conditional.
t - tests to see if the previous edit actually occurred. This is basically a version of branch that test status of last edit executed rather than an address. The test and branch may target the same label.
:label
[address]b[label]
sed -e ' # print the line pre-edit p # if the line contains 2 or more instances of the word house # change all but 1st to home :again s/\<house\>/home/2 t again # if the contains a series of slashes, convert all but the # 1st and last to star :sagain s#/#*#2 /\/\// b again p :pagain s/\*\*/*|/ t pagain' /home/lx/berezin/Data/myhouse
The following removes single blank lines between lines of text. If there are more than 1 consecutive blank lines, they are ignored.
#1st make sure blank lines are empty sed -e 's/^[ ]*$//' /home/lx/berezin/Data/linedata | sed -e ' #If line as text, skip edits. /^./ b # fetch next line N # If both lines blank, skip edits. /^\n$/b # if 2nd line not empty /^\n..*$/ { # Delete new line s/^\n// } ' | lessA word on multi-edit sed with embedded comments on the command line, bash is very forgiving of this style of command entry. If you find you need to work in a different shell, you may want to keep all your edits in a file and use sed -f to fetch them.
q - quit. Quits sed at current instruction on the current line. If
used with an address or condition, quit happens after line read in and back
out. Use this when you need to quit editing a file because of a certain
condition. The rest of the text file will not be read and so will not be
send to standard output.
First run the following :
w3m -T text/html /home/lx/berezin/Data/bad.html
Then :
sed '/<\/html>/ q' /home/lx/berezin/Data/bad.html|w3m -T text/html
This will terminate the processing and output of a file on encountering the closing html markup. This would be useful if you have a web page that has extra text after the closing markup.
The same could have been accomplished with :
sed -n '1,/<\/html>/ p' /home/lx/berezin/Data/bad.html|w3m -T text/html