Sed - An Introduction and Tutorial by Bruce Barnett
发布时间:2021-01-24 22:14:51 所属栏目:Linux 来源:网络整理
导读:http://www.grymoire.com/unix/sed.html Quick Links - NEW table border="1" tr Sed Pattern Flags /tr tr td a href="http://www.grymoire.com/unix/Sed.html#uh-6"gt;/g?- Global/td /tr tr td a href="http://www.grymoire.com/unix/Sed.html#uh-10a"gt;
The order of the delete command "d" and the read file command "r" is important. Change the order and it will not work. There are two subtle actions that prevent this from working. The first is the "r" command writes the file to the output stream. The file is not inserted into the pattern space,and therefore cannot be modified by any command. Therefore the delete command does not affect the data read from the file.
The other subtlety is the "d" command deletes the current data in the pattern space. Once all of the data is deleted,it does make sense that no other action will be attempted. Therefore a "d" command executed in a curly brace also aborts all further actions. As an example,the substitute command below is never executed:?
#!/bin/sh
# this example is WRONG
sed -e '1 {
d
s/.*//
}'
Click here to get file:?
The earlier example is a crude version of the C preprocessor program. The file that is included has a predetermined name. It would be nice if?sed?allowed a variable (e.g "1)" instead of a fixed file name. Alas,?sed?doesn't have this ability. You could work around this limitation by creating?sed?commands on the fly,or by using shell quotes to pass variables into the?sed?script. Suppose you wanted to create a command that would include a file like?cpp,but the filename is an argument to the script. An example of this script is:
% include 'sys/param.h' file.c.new
A shell script to do this would be:
#!/bin/sh
# watch out for a '/' in the parameter
# use alternate search delimiter
sed -e '_#INCLUDE <'"$1"'>_{
r '"$1"'
d
}'
Let me elaborate. If you had a file that contains
Test first file
#INCLUDE
Test second file
#INCLUDE
you could use the command
sed_include1.sh file1
to include the specified files.
Click here to get file:?
As we dig deeper into?sed,comments will make the commands easier to follow. The older versions of?sed?only allow one line as a comment,and it must be the first line. SunOS (and GNU's sed) allows more than one comment,and these comments don't have to be first. The last example could be:?
#!/bin/sh
# watch out for a '/' in the parameter
# use alternate search delimiter
sed -e '_#INCLUDE <'"$1"'>_{
# read the file
r '"$1"'
# delete any characters in the pattern space
# and read the next line in
d
}'
Click here to get file:?
Sed?has three commands used to add new lines to the output stream. Because an entire line is added,the new line is on a line by itself to emphasize this. There is no option,an entire line is used,and it must be on its own line. If you are familiar with many UNIX utilities,you would expect?sed?to use a similar convention: lines are continued by ending the previous line with a "". The syntax to these commands is finicky,like the "r" and "w" commands.
The "a" command appends a line after the range or pattern. This example will add a line after every line with "WORD:"?
#!/bin/sh
sed '
/WORD/ a
Add this line after every line with WORD
'
Click here to get file:?
You could eliminate two lines in the shell script if you wish:?
#!/bin/sh
sed '/WORD/ a
Add this line after every line with WORD'
Click here to get file:?
I prefer the first form because it's easier to add a new command by adding a new line and because the intent is clearer. There must not be a space after the "".
You can insert a new line before the pattern with the "i" command:?
#!/bin/sh
sed '
/WORD/ i
Add this line before every line with WORD
'
Click here to get file:?
You can change the current line with a new line.?
#!/bin/sh
sed '
/WORD/ c
Replace the current line with the line
'
Click here to get file:?
A "d" command followed by a "a" command won't work,as I discussed earlier. The "d" command would terminate the current actions. You can combine all three actions using curly braces:?
#!/bin/sh
sed '
/WORD/ {
i
Add this line before
a
Add this line after
c
Change the line to this one
}'
Click here to get file:?
Sed?ignores leading tabs and spaces in all commands. However these white space characters may or may not be ignored if they start the text following a "a," "c" or "i" command. In SunOS,both "features" are available. The Berkeley (and Linux) style sed is in /usr/bin,and the AT&T version (System V) is in /usr/5bin/.
To elaborate,the?/usr/bin/sed?command retains white space,while the?/usr/5bin/sed?strips off leading spaces. If you want to keep leading spaces,and not care about which version of?sed?you are using,put a "" as the first character of the line: