Chinaunix首页 | 论坛 | 博客
  • 博客访问: 57303
  • 博文数量: 28
  • 博客积分: 823
  • 博客等级: 军士长
  • 技术积分: 250
  • 用 户 组: 普通用户
  • 注册时间: 2010-06-10 16:58
文章分类

全部博文(28)

文章存档

2011年(1)

2010年(27)

我的朋友

分类: LINUX

2010-08-20 22:47:53

1.简介

sed是源于行编辑器ed的非交互式的流(stream-oriented)编辑器。sed之所以称为“流”编辑器,是因为象大多数UNIX程序一样,输入流过它,然后被导向标准输出。sed编辑器逐行处理文件(或输入),把当前处理的行存储在称为模式空间pattern space)的临时缓冲区中,接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。sed处理完一行后将其从模式空间中删除,然后读入下一行进行处理和输出。sed是对文件副本进行编辑和修改,所以不用担心会修改或破坏原文件。sed主要用来自动编辑一个或多个文件,简化对文件的反复操作和编写转换程序等。   

2. 使用格式

sed的使用格式如下:

sed [-n] [-e]  instruction file(s)
sed [-n] –f  scriptfile  file(s)

sedinstruction格式如下:

[address[,address]][!]command [arguments]

3.选项

sed的主要选项有:

 

 

-n

取消默认的输出

-e

允许多行编辑

-f

指定sed脚本文件名

-i[SUFFIX]

修改原文件,如果提供suffix,作备份

-r

使用扩展正则表达式

4. 指令地址

sed指令可以指定012个地址:

0)  命令应用于所有行;

1)  命令令应用于任何符合这一地址的行

2)  命令应用与从第1个地址到第2个地址之间的行

5. 命令(command)

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 spacepattern space的内容

     b

Branch(跳转)命令([address]b[label]

     t

Test(测试)命令([address]t[label])

5. sed正则表达式元字符

元字符

使 

.

除换行(\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\>/

6. sed脚本编程

 在命令行使用sed时常常会涉及到和shell的交互,而使用sed脚本则完全不必要为此操心。不再用引号来确保sed命令不被shell解释,而且可用反斜杠来续行。另外,对于脚本中的多个指令,应注意sed是对一行使用完了所有指令后再转到下一行的。sed的这种选择使得它可以方便地处理大文件(不必将整个文件一次读进内存)。另外,应注意sed对于脚本中输入的命令非常挑剔,在命令的末尾不能有任何空白或文本,如果在一行中有多个命令,要用分号分隔。开始的{后不许有空格,结束的}必须单起一行。这一点与awk的比较自由的使用方式形成对比。sed中使用多行指令的示例如下:

/^\.TS/,/^\.TE/{
/^$/d
s/^\.ps 10/.ps 8/
s/^\.vs 12/.vs 10/
}

7. sed中使用shell变量

sed如何使用shell变量?比如在shell中定义了一个var变量,如何在sed中调用此变量?可以考虑以下方法:

  •   将平常的单引号改为双引号(Shell里单引号中所有字符都作字面解释):

sed "s/mytext/$var/g" file

对于某些mytext这种方法可能不起作用。

  • 将一个单引号改为两个:

sed 's/mytext/'$var'/g' file

8.理解与补充说明

  • grepsed的区别。grep ‘John’ datafile对应的sed命令是sed –n ‘/John/p’ datafile。区别:

1)使用grep时,正则表达式没有包含在//分隔符中,而sed需要包含在//之间;

2sed默认会输出每一行,所以需要用-n命令阻止默认输出;

3)返回状态。如果grep在文件中找到指定模式,将返回状态0,否则返回1sed

不管是否找到指定模式,它的退出状态都是0,只有命令存在语法错误时,sed

退出状态才不是0

     sed为什么要设计得如此“麻烦”呢?初用者在想只输出匹配行时往往忘记加-n选项。

这是因为sed首先是一个编辑器,而不是一个查找工具。比如当我们需要替换文件的

一部分时可以用不加-n选项的sed ‘s/a/b/g’ file实现。

  • 比较seded/vi理解ed/vicurrent-line addressingsedglobal line addressing非常重要:在ed/vi中使用定址来扩展命令处理行;而在sed中使用定址来限制处理的行。在ed/vi中,除非你告诉处理哪些行,不会处理什么,而在sed中,它将工作于每一行除非你告诉它不处理。
  • 关于命令括在单引号中。这不是必须的,但是应养成总是这样做的良好习惯。单引号对可以避免shell解释在编辑指令中出现的特殊字符或空格(shell使用空格来分别提交给程序的不同参数,对于shell的特别字符在命令调用之前被扩展),所以当指令中存在空格时是必须使用单引号的。
  • sed注释#用来注释。System V只认第一列的#,而GNU sed则可以将#符号放在任何地方。但是注意,如果第一二个字符是#n 表示脚本不会自动输出结果,相当于指定了一个命令行参数-n
  • 在命令行中使用多指令的三种方法。1)在指令之间加分号;(2)在每一指令之前加-e;(3)使用Shell的多行记录功能(前面加后可以直接换行,shell会等待用户输入后再解释。
  • 最新版本的-i选项可以很方便地实现多文件直接修改,值得好好注意。

9.参考文献

【1】       Qingley.李化等译. UNIX shell范例精解.北京:清华大学出版社. 2007.5

【2】       Dale Dougherty & Arnold Robbins. Sed & Awk. Second Edition, March 1997.

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