Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2422844
  • 博文数量: 298
  • 博客积分: 7876
  • 博客等级: 准将
  • 技术积分: 5500
  • 用 户 组: 普通用户
  • 注册时间: 2011-02-23 13:39
文章存档

2013年(2)

2012年(142)

2011年(154)

分类: Python/Ruby

2012-04-07 21:56:13

使用SED

Sed接受一个或多个编辑命令,并且每读入一行后就依次应用这些命令。
当读入第一行输入后,sed对其应用所有的命令,然后将结果输出。接着再读入第二
行输入,对其应用所有的命令……并重复这个过程。上一个例子中sed由标准输入设
备(即命令解释器,通常是以管道输入的形式)获得输入。在命令行给出一个或多
个文件名作为参数时,这些文件取代标准输入设备成为sed的输入。sed的输出将被
送到标准输出(显示器)。因此:

 cat filename | sed '10q'         # 使用管道输入
 sed '10q' filename               # 
同样效果,但不使用管道输入
 sed '10q' filename > newfile     # 
将输出转移(重定向)到磁盘上

要了解sed命令的使用说明,包括如何通过脚本文件(而非从命令行)来使用这些命
令,请参阅《sed & awk》第二版,作者Dale DoughertyArnold Robbins
O'Reilly1997),《UNIX Text Processing》,作者
Dale Dougherty
Tim O'ReillyHayden Books1987)或者是Mike Arst写的教
程——压缩包的名称是“U-SEDIT2.ZIP”(在许多站点上都找得到)。要发掘sed
的潜力,则必须对“正则表达式”有足够的理解。正则表达式的资料可以看
Mastering Regular Expressions》作者Jeffrey FriedlO'reilly 1997)。
Unix
系统所提供的手册页(“man”)也会有所帮助(试一下这些命令
man sed”、“man regexp”,或者看“man ed”中关于正则表达式的部分),但
手册提供的信息比较“抽象”——这也是它一直为人所诟病的。不过,它本来就不
是用来教初学者如何使用sed或正则表达式的教材,而只是为那些熟悉这些工具的人
提供的一些文本参考。

引号语法:

前面的例子对sed命令基本上都使用单引号('...')而非双引号
"...")这是因为sed通常是在Unix平台上使用。单引号下,Unixshell(命令
解释器)不会对美元符($)和后引号(`...`)进行解释和执行。而在双引号下
美元符会被展开为变量或参数的值,后引号中的命令被执行并以输出的结果代替
后引号中的内容。而在“csh”及其衍生的shell中使用感叹号(!)时需要在其前
面加上转义用的反斜杠(就像这样:\!)以保证上面所使用的例子能正常运行
(包括使用单引号的情况下)。DOS版本的Sed则一律使用双引号("...")而不是
引号来圈起命令。

'\t'的用法

为了使本文保持行文简洁,我们在脚本中使用'\t'来表示一个制表
符。但是现在大部分版本的sed还不能识别'\t'的简写方式,因此当在命令行中为
脚本输入制表符时,你应该直接按TAB键来输入制表符而不是输入'\t'。下列的工
具软件都支持'\t'做为一个正则表达式的字元来表示制表符:awkperlHHsed
sedmod
以及GNU sed v3.02.80

不同版本的SED

不同的版本间的sed会有些不同之处,可以想象它们之间在语法上
会有差异。具体而言,它们中大部分不支持在编辑命令中间使用标签(:name)或分
支命令(b,t),除非是放在那些的末尾。这篇文档中我们尽量选用了可移植性较高
的语法,以使大多数版本的sed的用户都能使用这些脚本。不过GNU版本的sed允许使
用更简洁的语法。想像一下当读者看到一个很长的命令时的心情:

   sed -e '/AAA/b' -e '/BBB/b' -e '/CCC/b' -e d

好消息是GNU sed能让命令更紧凑:

   sed '/AAA/b;/BBB/b;/CCC/b;d'      # 甚至可以写成
   sed '/AAA\|BBB\|CCC/b;d'

此外,请注意虽然许多版本的sed接受象“/one/ s/RE1/RE2/”这种在's'前带有空
格的命令,但这些版本中有些却不接受这样的命令:/one/! s/RE1/RE2/”。这时
只需要把中间的空格去掉就行了。

速度优化:

当由于某种原因(比如输入文件较大、处理器或硬盘较慢等)需要提高
命令执行速度时,可以考虑在替换命令(“s/.../.../”)前面加上地址表达式来
提高速度。举例来说:

   sed 's/foo/bar/g' filename         # 标准替换命令
   sed '/foo/ s/foo/bar/g' filename   # 
速度更快
   sed '/foo/ s//bar/g' filename      # 
简写形式

当只需要显示文件的前面的部分或需要删除后面的内容时,可以在脚本中使用“q
命令(退出命令)。在处理大的文件时,这会节省大量时间。因此:

   sed -n '45,50p' filename           # 显示第4550
   sed -n '51q;45,50p' filename       # 
一样,但快得多

部分GNU sed扩展:

   转自:%3D1%26filter%3Ddigest%26digest%3D1%26digest%3D1

  1、\U \L \u \l
        大小写转换

  1. ly5066113@ubuntu:~$ echo 'abc' | sed 's/.*/\U&/'
  2. ABC
  3. ly5066113@ubuntu:~$ echo 'abc' | sed 's/.*/\u&/'
  4. Abc
  5. ly5066113@ubuntu:~$ echo 'ABC' | sed 's/.*/\L&/'
  6. abc
  7. ly5066113@ubuntu:~$ echo 'ABC' | sed 's/.*/\l&/'
  8. aBC

2、/REGEXP/I
        正则匹配忽略大小写
  1. ly5066113@ubuntu:~$ echo 'AbC' | sed -n '/abc/Ip'
  2. AbC

3、FIRST~STEP
        取出奇数行或者偶数行
  1. ly5066113@ubuntu:~$ seq 10 | sed '0~2d'
  2. 1
  3. 3
  4. 5
  5. 7
  6. 9
  7. ly5066113@ubuntu:~$ seq 10 | sed '1~2d'
  8. 2
  9. 4
  10. 6
  11. 8

每5行合并成1行,类似 xargs -n5
  1. ly5066113@ubuntu:~$ seq 20 | xargs -n5
  2. 1 2 3 4 5
  3. 6 7 8 9 10
  4. 11 12 13 14 15
  5. 16 17 18 19 20
  6. ly5066113@ubuntu:~$ seq 20 | sed ':a;N;s/\n/ /;0~5b;ba'
  7. 1 2 3 4 5
  8. 6 7 8 9 10
  9. 11 12 13 14 15
  10. 16 17 18 19 20

4、\%REGEXP%
        进行路径匹配时,使用此方法,可以剩去很多转义符\
  1. 16 17 18 19 20
  2. ly5066113@ubuntu:~$ echo 'a/b/c/d/e/f' | sed -n '/a\/b\/c\/d/p'
  3. a/b/c/d/e/f
  4. ly5066113@ubuntu:~$ echo 'a/b/c/d/e/f' | sed -n '\%a/b/c/d%p'
  5. a/b/c/d/e/f

5、ADDR1,+N
        地址 +行数,可以实现类似 grep -A N 的功能
  1. ly5066113@ubuntu:~$ seq 10 | grep -A2 '5'
  2. 5
  3. 6
  4. 7
  5. ly5066113@ubuntu:~$ seq 10 | sed -n '/5/,+2p'
  6. 5
  7. 6
  8. 7

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