Chinaunix首页 | 论坛 | 博客
  • 博客访问: 695888
  • 博文数量: 160
  • 博客积分: 8847
  • 博客等级: 中将
  • 技术积分: 1656
  • 用 户 组: 普通用户
  • 注册时间: 2010-11-25 16:46
个人简介

。。。。。。。。。。。。。。。。。。。。。。

文章分类

全部博文(160)

文章存档

2015年(1)

2013年(1)

2012年(4)

2011年(26)

2010年(14)

2009年(36)

2008年(38)

2007年(39)

2006年(1)

分类: BSD

2011-04-10 23:06:58

一、SED的特点:
  • sed是一个流编辑器,非交互式,不影响编辑的源文件。
  • sed分为好多个版本,但大多数支持主流的正则表达式(对正则表达式中的元字符支持的比较少,支持一部分)。每个unix或者linux版本都带有sed。
[root@ /UNIX]# sed --version
GNU sed version 4.2.1
Copyright (C) 2009 Free Software Foundation, Inc.

二、sed的工作方式:
一行一行的处理输入的文本,每一行首先被放入临时的缓存(也可以叫模式空间pattern space),然后处理完成后或者重定向到另一个位置(一个新文件)或者打印到屏幕(默认),然后从缓存移除该行,然后接着处理下一行,直到处理完成。

三、sed的返回值:
csh echo $status
bash echo $?
返回值(各个版本不太一样,我测试的版本是这样的):
0 -- 表示找到或者未找到,未发生错误
1 -- 出错,包括语法错误、正则错误等

[root@ /UNIX]# sed -n '/root/p' /etc/passwd
root:*:0:0:Charlie &:/root:/usr/local/bin/bash
toor:*:0:0:Bourne-again Superuser:/root:
daemon:*:1:1:Owner of many system processes:/root:/usr/sbin/nologin
[root@ /UNIX]# echo $?
0
[root@ /UNIX]# sed -n '/root/xx' /etc/passwd
sed: -e expression #1, char 8: extra characters after command
[root@ /UNIX]# echo $?
1


三、sed的语法:
sed [选项] '/[正则表达式]/[命令]' 带处理的文本 [ [> 新文本] | [下一个命令] ]
sed -n '/RE/p' filename
sed -n 's/RE/replacement String/g' filename

四、sed中的元字符
^ 行首 /^love/ 匹配以love开始的行
$ 行尾 /love$/ 匹配以love结尾的行
. 匹配一个字符,但是不是新的行的字符 /L..e/ 匹配以L开始,后面跟2个字符,最后跟一个e
* 粘帖前一个字符,0个或者多个前一字符 / *love/ 匹配0个或者多个空格,后面跟love
[] 匹配[]中的任意一个字符 /[Ll]ove/匹配love或者Love
\(\) 分组,从左到右编号,最多有9个分组,第一个分组为1,用\1表示 s/\(love\)able/\1er/ 替换loveable为lover
& 存储找到的字符 s/love/**&**/ 替换love为**love**
\< 单词开始 /\\> 单词结尾 /love\>/匹配以love结尾的单词
x\{m\} 粘帖前一个字符或者分组,m次重复
x\{m,\} 粘帖前一个字符或者分组,至少m次重复,多者不限
x\{m,n\} 粘帖前一个字符或者分组,至少m次重复,但不超过n次

注:在sed中\w \d \s 这些元字符不支持。
[root@ /UNIX]# /usr/bin/sed.bak 's/\d\{2\}$/&.5/' datafile
1:northwest     NW              Charles Main            3.0     .98     3       34
2:western       WE              Sharon Gray             5.3     .97     5       23
3:southwest     SW              Lewis Dalsass           2.7     .8      2       18
4:southern      SO              Suan Chin               5.1     .95     4       15
5:southeast     SE              Patricia Hemenway       4.0     .7      4       17
6:eastern       EA              TB Savage               4.4     .84     5       20
7:northeast     NE              AM Main Jr.             5.1     .94     3       13
8:north         NO              Margot Weber            4.5     .89     5       9
9:central       CT              Ann Stephens            5.7     .94     5       13

[root@ /UNIX]# /usr/bin/sed.bak 's/[0-9][0-9]$/&.5/' datafile
1:northwest     NW              Charles Main            3.0     .98     3       34.5
2:western       WE              Sharon Gray             5.3     .97     5       23.5
3:southwest     SW              Lewis Dalsass           2.7     .8      2       18.5
4:southern      SO              Suan Chin               5.1     .95     4       15.5
5:southeast     SE              Patricia Hemenway       4.0     .7      4       17.5
6:eastern       EA              TB Savage               4.4     .84     5       20.5
7:northeast     NE              AM Main Jr.             5.1     .94     3       13.5
8:north         NO              Margot Weber            4.5     .89     5       9
9:central       CT              Ann Stephens            5.7     .94     5       13.5

sed中默认使用"/"作为分界线,但是在s命令的时候,可以进行替换
sed -n '\cREcp' fiename 使用c作为分界线

五、定址:
sed使用定址的方式处理行,定址可以使用行号(从1开始)或者正则表达式定址,也可以使用两种方式的组合,如果不定址,就处理全文。

sed '1, 3d' myfile 三次1~3行
sed -n '/[Jj]ohn/p' datafile 打印包含john/John的行

六、sed的命令有十几个,s、a\、c\、d、p、r、!等,下面逐一举例说明:
p(print)命令:
一般和选项-n 一起使用,打印选择的行
sed -n '/north/p' datafile
打印包含north的行,如果不使用-n,就把全文打出来的同时,在匹配的行下面再打印一次匹配行。

  • d(delete)命令:
删除匹配的行后打印其他剩余的行
sed '3d' datafile 删除第三行,剩余行打印
sed '3,$d' datafile 删除3到最后一行,剩余的行打印
sed '$d' datafile 删除最后一行
sed '1d' datafile 删除第一行
sed '/north/d' datafile 删除包含north的行,其他行打印出来

  • s(substitution)替换命令:
替换找到的模式为新的字符,如果使用g,所有匹配都替换,否则只替换行中找到的第一个
sed 's/west/north/g' datafile
全行替换west为north,不加g选项,即使一行中出现若干次的west,只替换第一个。
sed -n 's/^west/north/p' datafile
[root@ /UNIX]# sed -n 's/west/north/gp' datafile
1:northnorth     NW              Charles Main            3.0     .98     3       34
2:northern       WE             Sharon Gray             5.3     .97     5       23
3:southnorth     SW              Lewis Dalsass           2.7     .8      2       18
sed找到west,并替换为north,打印这些替换的行。
[root@ /UNIX]# sed -n 's/\(Mar\)got/\1ianne/p' datafile
8:north         NO              Marianne Weber            4.5     .89     5       9
用\1表示找到的的第一个模式Margot的Mar部分,并替换为将Mar部分后面加ianne。

在s命令中使用其他界定符
s命令使用新的字符串替换匹配字符串,默认的界定符是“/”,但是如果你喜欢或者处于查找默认界定符的目的
你可以使用别的界定符。
sed 's#3#88#g' datafile
[root@ /UNIX]# sed -n 's#north#liujun#pg' datafile
1:liujunwest     NW              Charles Main            3.0     .98     3       34
7:liujuneast     NE              AM Main Jr.             5.1     .94     3       13
8:liujun         NO              Margot Weber            4.5     .89     5       9

[root@ /UNIX]# cat datafile
1:northwest     NW              Charles Main            3.0     .98     3       34
2:western       WE              Sharon Gray             5.3     .97     5       23
3:southwest     SW              Lewis Dalsass           2.7     .8      2       18
4:southern      SO              Suan Chin               5.1     .95     4       15
5:southeast     SE              Patricia Hemenway       4.0     .7      4       17
6:eastern       EA              TB Savage               4.4     .84     5       20
7:northeast     NE              AM Main Jr.             5.1     .94     3       13
8:north         NO              Margot Weber            4.5     .89     5       9
9:central       CT              Ann Stephens            5.7     .94     5       13
10:liujun       LJ              10/10/1981              4.0     .88     3       20

[root@ /UNIX]# sed -n 's#10/10/1981#1/1/81#pg' datafile
10:liujun       LJ              1/1/81          4.0     .88     3       20

sed可以通过逗号","来界定一个选择的范围进行处理,这个范围开始与某一个地址,结束于另一个地址。
地址的范围可以使用行号(如:5,10)来界定,也可以使用正则表达式界定(如:/Dick/,/Joe/),也可以使用
这两种的混合方式(如:5,$或者/north/, 7)。

选择的范围包括起始行及中间的所有行。
如果结束的范围没有到达,就一直处理到结束行;如果结束行到达,那么在剩余的部分继续开始匹配新的起始行。
[root@ /UNIX]# cat datafile | sed '5i\11:northAddNewLine NL NewLineAdd' | sed -n '/north/,/south/p'
1:northwest     NW              Charles Main            3.0     .98     3       34
2:western       WE              Sharon Gray             5.3     .97     5       23
3:southwest     SW              Lewis Dalsass           2.7     .8      2       18

11:northAddNewLine NL NewLineAdd
5:southeast     SE              Patricia Hemenway       4.0     .7      4       17

7:northeast     NE              AM Main Jr.             5.1     .94     3       13
8:north         NO              Margot Weber            4.5     .89     5       9
9:central       CT              Ann Stephens            5.7     .94     5       13
10:liujun       LJ              10/10/1981              4.0     .88     3       20
这里有3个符号条件的选择范围1~3,11~5和7~$,因为第三个范围没有找到south,所以直到所有行完成。

[root@ /UNIX]# sed -n '5,/^[0-9]:northeast/p' datafile
5:southeast     SE              Patricia Hemenway       4.0     .7      4       17
6:eastern       EA              TB Savage               4.4     .84     5       20
7:northeast     NE              AM Main Jr.             5.1     .94     3       13
打印从第5行开始到以一个数字开始,后面跟一个冒号(:),再跟northeast的行,把这些选择的行打印出来。

[root@ /UNIX]# sed -n '/west/,/east/s/$/**VACA**/p' datafile
1:northwest     NW              Charles Main            3.0     .98     3       34**VACA**
2:western       WE              Sharon Gray             5.3     .97     5       23**VACA**
3:southwest     SW              Lewis Dalsass           2.7     .8      2       18**VACA**
4:southern      SO              Suan Chin               5.1     .95     4       15**VACA**
5:southeast     SE              Patricia Hemenway       4.0     .7      4       17**VACA**
选择匹配模式,然后替换行尾为**VACA**

  • e命令(用于多重编辑):
对于在模式空间中的某一行,如果需要执行多个sed命令,可以使用-e
注意:多重编辑中,p命令和其他如:d、s命令不能同时
[root@ /UNIX]# sed -ne '1d' -e '/west/,/south/p'  datafile
2:western       WE              Sharon Gray             5.3     .97     5       23
3:southwest     SW              Lewis Dalsass           2.7     .8      2       18
[root@ /UNIX]# sed -ne '1d' -e '/west/,/south/p' -e '/west/,/south/d' datafile
2:western       WE              Sharon Gray             5.3     .97     5       23
3:southwest     SW              Lewis Dalsass           2.7     .8      2       18
上面这个例子中,第三次编辑删除d命令并不起作用,这是因为,第二重编辑已经把内容打印出来了,你删除只是删除了
模式空间中的,打印出来的没法删除了(因为已经打印在屏幕上了)。
所以这样的用法也是错的:
[root@ /UNIX]# sed -ne '/west/, /south/p' -ne 's/west/WEST/p' datafile
1:northwest     NW              Charles Main            3.0     .98     3       34
1:northWEST     NW              Charles Main            3.0     .98     3       34
2:western       WE              Sharon Gray             5.3     .97     5       23
2:WESTern       WE              Sharon Gray             5.3     .97     5       23
3:southwest     SW              Lewis Dalsass           2.7     .8      2       18
3:southWEST     SW              Lewis Dalsass           2.7     .8      2       18

sed -e '/west/, /south/{s/west/WEST/p}'   datafile

  • r(read)读命令:
[root@ /UNIX]# cat newfile
1:northwest     NW              Charles Main            3.0     .98     3       34
7:northeast     NE              AM Main Jr.             5.1     .94     3       13
8:north         NO              Margot Weber            4.5     .89     5       9

[root@ /UNIX]# sed -e '/Suan/r newfile' datafile
1:northwest     NW              Charles Main            3.0     .98     3       34
2:western       WE              Sharon Gray             5.3     .97     5       23
3:southwest     SW              Lewis Dalsass           2.7     .8      2       18
4:southern      SO              Suan Chin               5.1     .95     4       15
1:northwest     NW              Charles Main            3.0     .98     3       34
7:northeast     NE              AM Main Jr.             5.1     .94     3       13
8:north         NO              Margot Weber            4.5     .89     5       9
5:southeast     SE              Patricia Hemenway       4.0     .7      4       17
6:eastern       EA              TB Savage               4.4     .84     5       20
7:northeast     NE              AM Main Jr.             5.1     .94     3       13
8:north         NO              Margot Weber            4.5     .89     5       9
9:central       CT              Ann Stephens            5.7     .94     5       13
10:liujun       LJ              10/10/1981              4.0     .88     3       20

找到匹配的模式,然后读取一个文件到匹配模式下面的行,然后继续显示其他剩余行。如果找到多次,会多次读入该文件的内容。

  • w(write)写命令:
sed虽然不会影响自身编辑的文件,但是可以使用w创建新的文件。
[root@ /UNIX]# ls -l newFile
ls: newFile: No such file or directory
[root@ /UNIX]# sed -n '/south/w newFile' datafile
[root@ /UNIX]# cat newFile
3:southwest     SW              Lewis Dalsass           2.7     .8      2       18
4:southern      SO              Suan Chin               5.1     .95     4       15
5:southeast     SE              Patricia Hemenway       4.0     .7      4       17

  • a\(append)追加命令:
在找到匹配模式的下面,写入新的内容,这个命令和读差不多,区别是:r命令是读一个文件,a命令是读入新的行,这行的内容可以
直接在命令行提供,而不是读取另外一个文件。
csh需要使用a\\,如果插入的行是多行,除最后一行外,其他行需要用\结尾。

[root@ /UNIX]# sed -e '/north/a\\------------>edit<-----------\
> liujun \@ 2011.4' datafile
1:northwest     NW              Charles Main            3.0     .98     3       34
------------>edit<-----------
liujun @ 2011.4
2:western       WE              Sharon Gray             5.3     .97     5       23
3:southwest     SW              Lewis Dalsass           2.7     .8      2       18
4:southern      SO              Suan Chin               5.1     .95     4       15
5:southeast     SE              Patricia Hemenway       4.0     .7      4       17
6:eastern       EA              TB Savage               4.4     .84     5       20
7:northeast     NE              AM Main Jr.             5.1     .94     3       13
------------>edit<-----------
liujun @ 2011.4
8:north         NO              Margot Weber            4.5     .89     5       9
------------>edit<-----------
liujun @ 2011.4
9:central       CT              Ann Stephens            5.7     .94     5       13
10:liujun       LJ              10/10/1981              4.0     .88     3       20

  • i\(insert)插入命令:
这个命令和a\相似,区别是:插入是在匹配模式的前面,而不是后面。
[root@ /UNIX]# sed -e '/north/i\\------------>edit<-----------\
liujun \@ 2011.4' datafile
------------>edit<-----------
liujun @ 2011.4
1:northwest     NW              Charles Main            3.0     .98     3       34
2:western       WE              Sharon Gray             5.3     .97     5       23
3:southwest     SW              Lewis Dalsass           2.7     .8      2       18
4:southern      SO              Suan Chin               5.1     .95     4       15
5:southeast     SE              Patricia Hemenway       4.0     .7      4       17
6:eastern       EA              TB Savage               4.4     .84     5       20
------------>edit<-----------
liujun @ 2011.4
7:northeast     NE              AM Main Jr.             5.1     .94     3       13
------------>edit<-----------
liujun @ 2011.4
8:north         NO              Margot Weber            4.5     .89     5       9
9:central       CT              Ann Stephens            5.7     .94     5       13
10:liujun       LJ              10/10/1981              4.0     .88     3       20

  • c(change)改变当前行内容命令:
[root@ /UNIX]# sed -e '/eastern/c\&**ch**' datafile
1:northwest     NW              Charles Main            3.0     .98     3       34
2:western       WE              Sharon Gray             5.3     .97     5       23
3:southwest     SW              Lewis Dalsass           2.7     .8      2       18
4:southern      SO              Suan Chin               5.1     .95     4       15
5:southeast     SE              Patricia Hemenway       4.0     .7      4       17
&**ch**
7:northeast     NE              AM Main Jr.             5.1     .94     3       13
8:north         NO              Margot Weber            4.5     .89     5       9
9:central       CT              Ann Stephens            5.7     .94     5       13
10:liujun       LJ              10/10/1981              4.0     .88     3       20

这里&并不起作用,在s命令中&是找到的匹配字符串
[root@ /UNIX]# sed -n 's/eastern/&:I GOT IT/p' datafile
6:eastern:I GOT IT       EA              TB Savage               4.4     .84     5       20

  • n(next)下一行命令和q(quit)退出处理命令:
找到匹配行后执行n,会读取匹配行的下一行到模式空间中,并在这行上执行命令。
[root@ /UNIX]# sed '/eastern/{n;s/AM/Archie/;q;}' datafile
1:northwest     NW              Charles Main            3.0     .98     3       34
2:western       WE              Sharon Gray             5.3     .97     5       23
3:southwest     SW              Lewis Dalsass           2.7     .8      2       18
4:southern      SO              Suan Chin               5.1     .95     4       15
5:southeast     SE              Patricia Hemenway       4.0     .7      4       17
6:eastern       EA              TB Savage               4.4     .84     5       20
7:northeast     NE              Archie Main Jr.             5.1     .94     3       13
先匹配包含eastern的行,找到以后直接跳到下一行执行替换命令s,执行完成后退出q。

  • y(translation)逐字转换命令,类似tr命令
[root@ /UNIX]# echo "linux" | tr "[:lower:]" "[:upper:]"
LINUX
[root@ /UNIX]# echo "abc" | tr "abcdefghijklmnopqrstuvwxyz" "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
ABC
[root@ /UNIX]# sed  '1,3y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/' datafile
1:NORTHWEST     NW              CHARLES MAIN            3.0     .98     3       34
2:WESTERN       WE              SHARON GRAY             5.3     .97     5       23
3:SOUTHWEST     SW              LEWIS DALSASS           2.7     .8      2       18
4:southern      SO              Suan Chin               5.1     .95     4       15
5:southeast     SE              Patricia Hemenway       4.0     .7      4       17
6:eastern       EA              TB Savage               4.4     .84     5       20
7:northeast     NE              AM Main Jr.             5.1     .94     3       13
8:north         NO              Margot Weber            4.5     .89     5       9
9:central       CT              Ann Stephens            5.7     .94     5       13
10:liujun       LJ              10/10/1981              4.0     .88     3       20

  • h(hold)和g(get)命令
h命令将当前处理的行从模式空间放到另外一个holding缓存中,g命令可以取出来。
[root@ /UNIX]# sed -e '/northeast/h' -e '$G' datafile
1:northwest     NW              Charles Main            3.0     .98     3       34
2:western       WE              Sharon Gray             5.3     .97     5       23
3:southwest     SW              Lewis Dalsass           2.7     .8      2       18
4:southern      SO              Suan Chin               5.1     .95     4       15
5:southeast     SE              Patricia Hemenway       4.0     .7      4       17
6:eastern       EA              TB Savage               4.4     .84     5       20
7:northeast     NE              AM Main Jr.             5.1     .94     3       13
8:north         NO              Margot Weber            4.5     .89     5       9
9:central       CT              Ann Stephens            5.7     .94     5       13
10:liujun       LJ              10/10/1981              4.0     .88     3       20
7:northeast     NE              AM Main Jr.             5.1     .94     3       13
[root@ /UNIX]# sed -e '/northeast/h' -e '$g' datafile
1:northwest     NW              Charles Main            3.0     .98     3       34
2:western       WE              Sharon Gray             5.3     .97     5       23
3:southwest     SW              Lewis Dalsass           2.7     .8      2       18
4:southern      SO              Suan Chin               5.1     .95     4       15
5:southeast     SE              Patricia Hemenway       4.0     .7      4       17
6:eastern       EA              TB Savage               4.4     .84     5       20
7:northeast     NE              AM Main Jr.             5.1     .94     3       13
8:north         NO              Margot Weber            4.5     .89     5       9
9:central       CT              Ann Stephens            5.7     .94     5       13
7:northeast     NE              AM Main Jr.             5.1     .94     3       13
取出命令有g和G两种模式,G取出后,追加到指定位置,而g替换掉指定位置。

[root@ /UNIX]# sed -e '/WE/{h;d}' -e '4G' datafile
1:northwest     NW              Charles Main            3.0     .98     3       34
3:southwest     SW              Lewis Dalsass           2.7     .8      2       18
4:southern      SO              Suan Chin               5.1     .95     4       15
2:western       WE              Sharon Gray             5.3     .97     5       23
5:southeast     SE              Patricia Hemenway       4.0     .7      4       17
6:eastern       EA              TB Savage               4.4     .84     5       20
7:northeast     NE              AM Main Jr.             5.1     .94     3       13
8:north         NO              Margot Weber            4.5     .89     5       9
9:central       CT              Ann Stephens            5.7     .94     5       13
10:liujun       LJ              10/10/1981              4.0     .88     3       20

[root@ /UNIX]# sed -e '{h;}' -e 'g;s/WE/EWE/;'   datafile
1:northwest     NW              Charles Main            3.0     .98     3       34
2:western       EWE             Sharon Gray             5.3     .97     5       23
3:southwest     SW              Lewis Dalsass           2.7     .8      2       18
4:southern      SO              Suan Chin               5.1     .95     4       15
5:southeast     SE              Patricia Hemenway       4.0     .7      4       17
6:eastern       EA              TB Savage               4.4     .84     5       20
7:northeast     NE              AM Main Jr.             5.1     .94     3       13
8:north         NO              Margot Weber            4.5     .89     5       9
9:central       CT              Ann Stephens            5.7     .94     5       13
10:liujun       LJ              10/10/1981              4.0     .88     3       20

[root@ /UNIX]# sed -e '/WE/{h;d}' -e '/CT/{G;}' datafile
1:northwest     NW              Charles Main            3.0     .98     3       34
3:southwest     SW              Lewis Dalsass           2.7     .8      2       18
4:southern      SO              Suan Chin               5.1     .95     4       15
5:southeast     SE              Patricia Hemenway       4.0     .7      4       17
6:eastern       EA              TB Savage               4.4     .84     5       20
7:northeast     NE              AM Main Jr.             5.1     .94     3       13
8:north         NO              Margot Weber            4.5     .89     5       9
9:central       CT              Ann Stephens            5.7     .94     5       13
2:western       WE              Sharon Gray             5.3     .97     5       23
10:liujun       LJ              10/10/1981              4.0     .88     3       20

  • x(exchange)交换命令,将当前holding缓存中的内容和模式空间中的内容交换。
[root@ /UNIX]# sed -e '/WE/{h;d;}' -e '/CT/{x;}' -ne '{$G;p;}' datafile
1:northwest     NW              Charles Main            3.0     .98     3       34
3:southwest     SW              Lewis Dalsass           2.7     .8      2       18
4:southern      SO              Suan Chin               5.1     .95     4       15
5:southeast     SE              Patricia Hemenway       4.0     .7      4       17
6:eastern       EA              TB Savage               4.4     .84     5       20
7:northeast     NE              AM Main Jr.             5.1     .94     3       13
8:north         NO              Margot Weber            4.5     .89     5       9
2:western       WE              Sharon Gray             5.3     .97     5       23
10:liujun       LJ              10/10/1981              4.0     .88     3       20
9:central       CT              Ann Stephens            5.7     .94     5       13
先找到WE,匹配后放到holding缓存,然后删除模式空间中的行;
再找CT,匹配后和当前模式空间中的行(第9行包含CT的行)和holding缓存中的行交换,即:将holding缓存中的行显示到第9行的位置;
然后从holding缓存中读取行(及包含CT的那行),放到所有行的末尾,打印到屏幕上。

(END)
阅读(1239) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~