The
sed
editor can manipulate data in a data stream based on commands you either enter into the command line or store in a command text file. The
sed
editor does these things:
1.
Reads one data line at a time from the input
2.
Matches that data with the supplied editor commands
3.
Changes data in the stream as specified in the commands
4.
Outputs the new data to
STDOUT
After the stream editor matches all the commands against a line of data, it reads the next line of data and repeats the process. After the stream editor processes all the lines of data in the stream, it terminates.
Here’s the format for using the
sed
command:
sed
options script file
Substituting flags
To get the
substitute
command to work on different occurrences of the text, you must use a
substitution flag
. The substitution flag is set after the substitution command strings:
s/pattern/replacement/flags
Four types of substitution flags are available:
- A number, indicating the pattern occurrence for which new text should be substituted $ sed 's/test/trial/2' data4.txt
- g, indicating that new text should be substituted for all occurrences of the existing text $ sed 's/test/trial/g' data4.txt
- p, indicating that the contents of the original line should be printed $ sed -n 's/test/trial/p' data5.txt
- w file, which means to write the results of the substitution to a file $ sed 's/test/trial/w test.txt' data5.txt
The
p
substitution flag prints a line that contains a matching pattern in the substitute command. This is most often used in conjunction with the
-n sed
option:
The
w
substitution flag produces the same output but stores the output in the specified file:
the
sed
editor allows you to select a different character for the string delimiter in the substitute command:
$
sed 's!/bin/bash!/bin/csh!' /etc/passwd
In this example, the exclamation point is used for the string delimiter, making the pathnames much easier to read and understand.
Using addresses
By default, the commands you use in the
sed
editor apply to all lines of the text data. If you want to apply a command only to a specific line or a group of lines, you must use
line addressing.
here are two forms of line addressing in the
sed
editor:
- A numeric range of lines
- A text pattern that filters out a line
Both forms use the same format for specifying the address:
[address]command
You can also group more than one command together for a specific address:
address { command1
command2
command3
}
Addressing the numeric line
$
sed '2s/dog/cat/' data1.txt
#
modified the text only in line two per the address specified
$
sed '2,3s/dog/cat/' data1.txt
# using a range of line addresses
$
sed '2,$s/dog/cat/' data1.txt
#
starting at some point within the text, but continuing to the end of the text, you can use the special
# address, the dollar sign
Using text pattern filters
The
sed
editor allows you to specify a text pattern that it uses to filter lines for the command. This is the format:
/pattern/command
You must encapsulate the
pattern
you specify in forward slashes. The
sed
editor applies the command only to lines that contain the text pattern you specify.
$
sed '/Samantha/s/bash/csh/' /etc/passwd
Deleting lines
The
delete
command,
d
, pretty much does what it says. It deletes any text lines that match the addressing scheme supplied.
$ sed 'd' data1.txt
#
if you forget to include an addressing scheme, all the lines are deleted from the stream
$ sed '3d' data6.txt #
delete specific lines of text from the data stream by line number:
$ sed '2,3d' data6.txt #
by a specific range of lines:
$ sed '3,$d' data6.txt #
by using the special end-of-file character:
$ sed '/number 1/d' data6.txt
#
The pattern-matching feature of the
sed
editor also applies to the
delete
command:
$ sed '/1/,/3/d' data6.txt
# The
sed
editor deletes any lines between the two specified lines
Inserting and appending text
- The insert command (i) adds a new line before the specified line.
- The append command (a) adds a new line after the specified line.
What is confusing about these two commands is their formats. You can’t use these com- mands on a single command line. You must specify the line to insert or append the line to insert on a separate line by itself. Here’s the format for doing this:
sed '[address] command\
new line'
Looking at Multiline Commands
Sometimes, you need to perform actions on data that spans more than one line. This is especially true if you’re trying to find or replace a phrase.
The
sed
editor includes three special commands that you can use to process multiline text:
- N adds the next line in the data stream to create a multiline group for processing.
- D deletes a single line in a multiline group.
- P prints a single line in a multiline group.
Navigating the next command
Using the single-line next command
The lowercase
n
command tells the
sed
editor to move to the next line of text in the data stream, without going back to the beginning of the commands. Remember that normally the
sed
editor processes all the defined commands on a line before moving to the next line of text in the data stream. The single-line
next
command alters this flow.
$
sed '/header/{n ; d}' data1.txt
This is the header line.
This is a data line.
This is the last line.
$
Combining lines of text
Now that you’ve seen the single-line
next
command, you can look at the multiline version. The single-line
next
command moves the next line of text from the data stream into the processing space (called the
pattern space
) of the
sed
editor. The multiline version of the
next
command (which uses a capital
N
) adds the next line of text to the text already in the pattern space.
This has the effect of combining two lines of text from the data stream into the same pat- tern space. The lines of text are still separated by a newline character, but the
sed
editor can now treat both lines of text as one line.
Here’s a demonstration of how the
N
command operates:
$
cat data2.txt
This is the header line.
This is the first data line.
This is the second data line.
This is the last line.
$
$
sed '/first/{ N ; s/\n/ / }' data2.txt
This is the header line.
This is the first data line. This is the second data line.
This is the last line.
$
sed 可以使用完整的正则表达式.但是应该知道”从最长的最左边”规则的重要性.
kang:~ haiyankang$
echo Tolstoy is worldly | sed 's/T.*y/Camus/'
Camus
kang:~ haiyankang$
很明显,我们只想要匹配 Tolstoy,但是由于匹配会扩展到可能的最长长度的文本量,所以出现了这样的结果.
这就需要我们精确定义:
kang:~ haiyankang$
echo Tolstoy is worldly | sed 's/T[[:alpha:]]*y/Camus/'
Camus is worldly
kang:~ haiyankang$