分类: LINUX
2010-08-20 22:47:53
sed是源于行编辑器ed的非交互式的流(stream-oriented)编辑器。sed之所以称为“流”编辑器,是因为象大多数UNIX程序一样,输入流过它,然后被导向标准输出。sed编辑器逐行处理文件(或输入),把当前处理的行存储在称为“模式空间”(pattern space)的临时缓冲区中,接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。sed处理完一行后将其从模式空间中删除,然后读入下一行进行处理和输出。sed是对文件副本进行编辑和修改,所以不用担心会修改或破坏原文件。sed主要用来自动编辑一个或多个文件,简化对文件的反复操作和编写转换程序等。
sed的使用格式如下:
sed [-n] [-e] ‘instruction’ file(s)
sed [-n] –f scriptfile file(s)
sed的instruction格式如下:
[address[,address]][!]command [arguments]
sed的主要选项有:
选 项 |
功 能 |
-n |
取消默认的输出 |
-e |
允许多行编辑 |
-f |
指定sed脚本文件名 |
-i[SUFFIX] |
修改原文件,如果提供suffix,作备份 |
-r |
使用扩展正则表达式 |
sed指令可以指定0、1或2个地址:
0) 命令应用于所有行;
1) 命令令应用于任何符合这一地址的行
2) 命令应用与从第1个地址到第2个地址之间的行
sed的命令主要有:
命 令 |
功 能 |
d |
删除行 |
p |
打印行 |
! |
对所选行之外的所有行应用命令 |
= |
打印行号 |
s |
替换命令(如’s/^west/north/g’)注意查找替换分隔符不必是’/’,而可以是换行符和反斜线外的任何字符(如s#^west#north#g) |
r |
读文件 |
w |
写文件 |
a\ |
在当前行后添加一行或多行 |
i\ |
在当前行之前插入文本 |
c\ |
用新文本代替当前行中的文本 |
l |
显示模式空间中的内容,显示非打印字符为两字节ASCII码 |
y |
将一字符转换为另一字符(如:[address]y/abc/xyz/) |
n |
读入下一行,并将其读入模式缓冲区中,任何命令都将应用于下一行 |
q |
结束或退出sed |
D |
删除多行pattern space中到\n为止 |
N |
将下一行附加到上一行 |
P |
打印到多行pattern space的\n为止 |
H(h) |
Hold命令,附加(H)或拷贝(h)pattern space的内容到hold space(暂存区) |
G(g) |
Get命令,附加(拷贝)暂存区的内容到pattern space |
x |
Exchange命令,互换hold space和pattern space的内容 |
b |
Branch(跳转)命令([address]b[label]) |
t |
Test(测试)命令([address]t[label]) |
元字符 |
使 用 |
. |
除换行(\n)之外的任何字符 |
* |
匹配0或多个前导字符,相当于\{0,\} (如:/*love/) |
+ |
匹配1或多个前导字符,相当于\{1,\} 注意这是扩展元字符 |
[...] |
匹配指定字符组内的任一字符 (如:/[Ll]ove/ |
\{n,m\} |
匹配至少n个,至多m个前导字符;\{n\} 将匹配正好 n个, \{n,\}将匹配至少n个 (如:/o\{5,10\}) |
^ |
行首定位符 |
$ |
行尾定位符 |
\ |
取消转义字符 |
\( \) |
保存已匹配的字符,最多可定义9个标签(如:s/\(love\)able/\1er/) |
\n |
获取以上获取的第n个标签 |
& |
保存查找串以便在替代串中引用 (如 s/love/**&**/g) |
\< |
词首定位符
/\ |
\> |
词尾定位符
/love\>/ |
在命令行使用sed时常常会涉及到和shell的交互,而使用sed脚本则完全不必要为此操心。不再用引号来确保sed命令不被shell解释,而且可用反斜杠来续行。另外,对于脚本中的多个指令,应注意sed是对一行使用完了所有指令后再转到下一行的。sed的这种选择使得它可以方便地处理大文件(不必将整个文件一次读进内存)。另外,应注意sed对于脚本中输入的命令非常挑剔,在命令的末尾不能有任何空白或文本,如果在一行中有多个命令,要用分号分隔。开始的{后不许有空格,结束的}必须单起一行。这一点与awk的比较自由的使用方式形成对比。sed中使用多行指令的示例如下:
/^\.TS/,/^\.TE/{
/^$/d
s/^\.ps 10/.ps 8/
s/^\.vs 12/.vs 10/
}
sed如何使用shell变量?比如在shell中定义了一个var变量,如何在sed中调用此变量?可以考虑以下方法:
sed "s/mytext/$var/g" file
对于某些mytext这种方法可能不起作用。
sed 's/mytext/'$var'/g' file
(1)使用grep时,正则表达式没有包含在//分隔符中,而sed需要包含在//之间;
(2)sed默认会输出每一行,所以需要用-n命令阻止默认输出;
(3)返回状态。如果grep在文件中找到指定模式,将返回状态0,否则返回1。sed则
不管是否找到指定模式,它的退出状态都是0,只有命令存在语法错误时,sed的
退出状态才不是0。
sed为什么要设计得如此“麻烦”呢?初用者在想只输出匹配行时往往忘记加-n选项。
这是因为sed首先是一个编辑器,而不是一个查找工具。比如当我们需要替换文件的
一部分时可以用不加-n选项的sed ‘s/a/b/g’ file实现。
【1】 Qingley著.李化等译. UNIX shell范例精解.北京:清华大学出版社. 2007.5
【2】 Dale Dougherty & Arnold Robbins. Sed & Awk. Second Edition, March 1997.