曲径通幽论坛

 找回密码
 立即注册
搜索
查看: 4758|回复: 2
打印 上一主题 下一主题

sed

[复制链接]

4918

主题

5880

帖子

3万

积分

GROAD

曲径通幽,安觅芳踪。

Rank: 6Rank: 6

积分
34397
跳转到指定楼层
楼主
发表于 2009-1-10 08:19:41 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
  sed 不与初始文件打交道,它操作的只是一个拷贝,然后所有的改动如果没有重定向到一个文件,将输出到屏幕。sed 是一种重要的文本过滤工具,使用一行命令或者使用管道与 grep以及awk相结合。它是非交性的文本流编辑。

一、调用 sed  的三种方式


1、使用 sed  命令行格式:  sed [选项] sed命令 输入文件
2、使用 sed  脚本文件  :    sed [选项] -f sed脚本文件 输入文件
3、sed脚本文件 [选项] 输入文件

不管是使用 shell 命令行方式或者脚本文件方式,如果没有指定输入文件,sed 从标准输入中接受输入,一般是键盘或重定向结果。

二、sed 命令选项
 
  n 不打印
  c 下一命令是编辑命令
  f 正在调用 sed 脚本文件

三、文件查询与操作

        x        行号
     x,y        表示行号范围从 x 到 y
 /pattern/       查询包含模式的行
/patter/pattern/   查询包含两个模式的行
pattern/,x        在给定行号上查询包含模式的行
      x,y!     查询不包含指定行号 x 和 y 的行

四、基本编辑命令
      p     打印匹配行
    =     显示文件行号
   a\   在定位行号后附加新文本信息
    i\    在定位行号前插入新文本信息
    d     删除定位行
    c\   用新文本替换定位文本
   s     使用替换模式替换相应模式
   r     从另一个文件中读文本
   w    写文本到一个文件
   q    第一个模式匹配完成后退出或立即退出
   l    显示与八进制 ASCII 代码等价的控制字符
    {}   在定位执行的命令组
   n    从另一个文件中读文本下一行,并附加在下一行
   g    将模式2粘贴到 /patter n/
   y  传送字符

Sed简明速查手册
Sed(a stream editor)
4个空间:input stream, pattern buffer, output stream和hold buffer
基本操作过程是:
(1).将input stream的当前行放入pattern buffer,然后input stream的指针指向下一行;
(2).对pattern buffer中的行进行处理;
(3).将2的处理结果放入output stream.然后循环这个过程.

hold buffer是另一个空间,可以通过命令和pattern buffer进行交互.

sed命令介绍

1. 基本命令---"替换": s
  1.1 基本用法
  e.g. sed 's/day/night/' <old >new
  该例子将文件old中的每一行第一次出现的day替换成night,将结果输出到文件new
  s            "替换"命令
  /../../      分割符(Delimiter)
  day          搜索字符串
  night        替换字符串

  其实,分割符"/"可以用别的符号代替,比如",", "|"等.
  e.g. sed 's/\/usr\/local\/bin/\/common\/bin/'<old >new
  等价于sed 's_/usr/local/bin_/common/bin_' <old >new
  显然,此时用"_"作分割符比"/"好得多.


  1.2 用&表示匹配的字符串

  有时可能会想在匹配到的字符串周围或附近加上一些字符.
  e.g. sed 's/abc/(abc)/' <old >new
  该例子在找到的abc前后加上括号.
  该例子还可以写成 sed 's/abc/(&)/' <old >new
  下面是更复杂的例子:
  sed 's/[a-z]*/(&)/' <old >new
  sed 's/[0-9]*/& &/' <old >new

  1.3 用\1, \2, ..., \9来表示匹配的字符串

  e.g. sed 's/\([a-z]*\)[0-9]*/\1/' <old >new
  本例中\1就是指前面的\([a-z]*\)

  sed 's/\([a-z]*\) \([0-9]*\)/\2 \1/' <old >new
  本例中\2和\1分别代表前面的\([0-9]*\)和\([a-z]*\)

  \1, \2, ..., \9也可以出现在搜索字符串中
  e.g. sed 's/\([a-z]*\) \1/\1/' <old >new
  本例可以去除重复的由字母组成的词

  1.4 "替换"选项
      1.4.1 /g 替换所有的
      sed默认只替换搜索字符串的第一次出现,利用/g可以替换搜索字符串所有
      出现的地方.例如,
      sed 's/\([^ ]*\)/(&)/g' <old >new

      1.4.2 用/1, /2, ...来表明替换哪一次出现
      e.g. sed 's/[^ ]*//2' <old >new
      可以从/1用到/512

      1.4.3 /p print选项
      当sed命令有-n选项时,该命令没用输出.
      -n配合/p选项后,如果该行确实发生了替换,则输出该行,否则不输出.

      1.4.4 /w filename 写到文件filename中
      e.g. sed 's/\([0-9]*\) \([a-z]*\)/\2/w new' <old
      该例子把输出放入文件new中

  1.5 替换和插入换行符号
  替换 (echo a;echo x;echo y) | sed '/x$/ {
       N
       s:x\n:x:
       }'

  插入
       (echo a;echo x;echo y) | sed 's:x:X\
       :'



2. 只对特定行的处理

  2.1 通过行号限定
  sed '3 s/[0-9][0-9]*//' <old >new 只处理第3行

  sed '1,100 s/A/a/' <old >new 只处理1到100行

  sed '101,$ s/A/a/' <old >new 处理101到文件的最后一行

  sed '101,$ !s/A/a/' <old >new 这里!表示只对1到100行进行替换,!的作用是取反


  2.2 通过正规表达式限定
  sed '/start/,/stop/ s/#.*//' <old >new
  本例中,sed先找到有start的行作为开始,找到最近的有stop的行作为结束,对之
  间的行进行操作.
  重复上述过程,直到文件结束

  下面这个例子是行号和正规表达式配合来限定
  sed '1,/start/ s/#.*//' <old >new 对第1行到含有start的行进行处理


3. 其他的简单命令
  3.1 删除命令 d
  sed '11,$ d' <old >new 删除从11行到文件末尾
  sed '/^#/ d' <old >new 删除所有以#开始的行

  3.2 print命令 p (注意与s命令的/p选项的区别)
  sed 'p' <old    每一行将会被输出两次
  sed -n 'p' <old 每一行将会输出一次(-n屏蔽掉一次)
  sed '/^$/ p' <old 只对空行输出两次,其他只输出一次
  sed -n '1,10 p' <old 输出前10行
  sed -n '/match/ p' <old 输出含有match的行

  3.3 quit命令 q
  sed '11 q'<old    输出前10行(在第11行退出)
  注意:q命令不能接收多行,例如
  sed '2,5 q'<old 是不正确的

  3.4 写入文件命令 w filename(注意与s命令的/w选项的区别)
  把某些行写入文件filename
  sed -n '/^[0-9]*[02468]/ w even' <old    将以偶数开始的行写入文件even

  3.5 输出行号命令 =
  sed -n '/PATTERN/ =' <old 遇到含有PATTERN的行时,同时输出行号

  3.6 追加,改变,插入新行
  追加命令 a
  #!/bin/sh
  sed '
  /WORD/ a\
  Add this line after every line with WORD
  '

  改变命令 c
  #!/bin/sh
  sed '
  /WORD/ c\
  Replace the current line with the line
  '

  插入命令 i
  #!/bin/sh
  sed '
  /WORD/ i\
  Add this line before every line with WORD
  '

  3.7 变换命令 y
  sed 'y/abcdef/ABCDEF/' <old  该例将字符abcdef分别变成大写

  3.8 将本行的控制符也显示出来的命令 l
  sed '1,10 l' <old

  3.9 d命令和D命令
  d命令删除pattern buffer中的内容进入下一次操作循环
  D命令删除pattern buffer中第一个换行符之前的内容进入下一次操作循环,如
  果pattern buffer中还有内容,则不用从input stream中读入

  3.10 p命令和P命令
  p命令输出pattern buffer中的内容
  P命令输出pattern buffer中第一个换行符之前的内容

  3.11 n命令和N命令
  n命令把下一行读入pattern buffer中(如果没用-n选项,将原来行输出)
  N命令把下一行追加到pattern buffer中

 3.12 流程控制命令
  b label命令:在指定行跳到label
  t label命令:如果在某行发生了替换,跳到label
  T label命令:如果在某行没有发生了替换,跳到label

4. 调用sed时的参数

  4.1 -e script 执行script这个脚本
  e.g. sed -e 's/a/A/' -e 's/b/B/' <old >new
  对每一行分别执行's/a/A/'和 's/b/B/'

  4.2 -n     禁止输出
  这里的-n与前面的/p配合,可以只输出被修改了的行.

  4.3 -f scriptname 把scriptname文件中的sed命令加入本次sed的调用中
  e.g. sed -f sedscript <old >new

  sedscript的内容可能是这样的:
  # sed comment - This script changes lower case vowels to upper case
  s/a/A/g
  s/e/E/g
  s/i/I/g
  s/o/O/g
  s/u/U/g

5. Hold Buffer

  x命令:将pattern buffer放入hold buffer,而将hold buffer的内容输出,pattern
  buffer的内容变成下一行
  h命令:将pattern buffer放入hold buffer,并将pattern buffer的内容输出,
  pattern buffer的内容变成下一行
  H命令:将pattern buffer追加到hold buffer
  g和G命令:g用hold buffer的内容替换pattern buffer的内容,而G将hold buffer内
  容追加到pattern buffer

4918

主题

5880

帖子

3万

积分

GROAD

曲径通幽,安觅芳踪。

Rank: 6Rank: 6

积分
34397
沙发
 楼主| 发表于 2009-1-10 18:14:48 | 只看该作者

sed 应用举例二

d 编辑命令的使用---删除掉指定的行
[beyes@localhost ~]$ cat pass.txt
yes:no:hi:hello:maybe:welcome

ok:awk:bird:amd:tmd:intel:ati

name:linux:unix:gnu:bsd:open
suse:ubuntu:fedora:redhat:now
china:usa:korea:japan:enland:old

mtime
[beyes@localhost ~]$ sed '1,4d' pass.txt
name:linux:unix:gnu:bsd:open
suse:ubuntu:fedora:redhat:now
china:usa:korea:japan:enland:old

mtime

& 编辑命令的使用(插入内容)
1、:centos 插在 ubuntu 之后
[beyes@localhost ~]$ sed 's/ubuntu/&:centos/' pass.txt
yes:no:hi:hello:maybe:welcome

ok:awk:bird:amd:tmd:intel:ati

name:linux:unix:gnu:bsd:open
suse:ubuntu:centos:fedora:redhat:now
china:usa:korea:japan:enland:old

2、centos: 插在 ubuntu 之前
[beyes@localhost ~]$ sed 's/ubuntu/centos:&/' pass.txt
yes:no:hi:hello:maybe:welcome

ok:awk:bird:amd:tmd:intel:ati

name:linux:unix:gnu:bsd:open
suse:centos:ubuntu:fedora:redhat:now
china:usa:korea:japan:enland:old

r 编辑命令---从另一个文件中读入内容:

4918

主题

5880

帖子

3万

积分

GROAD

曲径通幽,安觅芳踪。

Rank: 6Rank: 6

积分
34397
板凳
 楼主| 发表于 2009-1-10 11:30:47 | 只看该作者

sed 应用举例

本来想打印 pass.txt 中的第三行内容,但打印出的却是所有内容
[beyes@localhost ~]$ sed '3p' pass.txt
yes:no:hi:hello:maybe:welcome

ok:awk:bird:amd:tmd:intel:ati
ok:awk:bird:amd:tmd:intel:ati

name:linux:unix:gnu:bsd:open
suse:ubuntu:fedora:redhat:now
china:usa:korea:japan:enland:old

mtime

-n 参数(不打印---不打印不匹配的内容)应用举例
[beyes@localhost ~]$ sed -n '3p' pass.txt
ok:awk:bird:amd:tmd:intel:ati

打印 pass.txt 中的 1 - 4 行行号):
[beyes@localhost ~]$ sed -n '1,4p' pass.txt
yes:no:hi:hello:maybe:welcome
                                       
ok:awk:bird:amd:tmd:intel:ati
                               #第二行和第四行为空白行

打印出含有 hello 字符的行模式匹配):
[beyes@localhost ~]$ sed -n '/hello/p' pass.txt
yes:no:hi:hello:maybe:welcome

打印出文件中的空行的行号
[beyes@localhost ~]$ sed -n '/^$/=' pass.txt     # = ,打印出行号
2
4
8

打印出文件中的“空行”以及“行号”(-e参数的使用):
[beyes@localhost ~]$ sed -n -e '/^$/p' -e '/^$/=' pass.txt
                           # -e 参数指示使用了多条编辑命令
2

4

8

使用 a\\ 编辑命令
1、(有参数 -n 时,只要找到“mtime”(条件满足)就会进行追加动作,打印出append,文件中的其它内容不显示)
[beyes@localhost ~]$ sed -n '/mtime/a \\append' pass.txt
append

2、(无 -n 参数,找到“mtime”就产生追加动作,并则打印出文件其它内容<显示>)
[beyes@localhost ~]$ sed '/mtime/a \\append' pass.txt
yes:no:hi:hello:maybe:welcome

ok:awk:bird:amd:tmd:intel:ati

name:linux:unix:gnu:bsd:open
suse:ubuntu:fedora:redhat:now
china:usa:korea:japan:enland:old

mtime
append

使用 i\\ 编辑命令
[beyes@localhost ~]$ sed '/mtime/i\\append_front' pass.txt
yes:no:hi:hello:maybe:welcome

ok:awk:bird:amd:tmd:intel:ati

name:linux:unix:gnu:bsd:open
suse:ubuntu:fedora:redhat:now
china:usa:korea:japan:enland:old

append_front
mtime

------------可以保留修改后的文件---------------
sed '/mtime/i\\append_front' pass.txt > pass-new.txt

使用 c\\ 编辑命令替换文本
[beyes@localhost ~]$ sed '/mtime/c\\mtime-change' pass.txt
yes:no:hi:hello:maybe:welcome

ok:awk:bird:amd:tmd:intel:ati

name:linux:unix:gnu:bsd:open
suse:ubuntu:fedora:redhat:now
china:usa:korea:japan:enland:old

mtime-change



设有一文件 test.txt ,文件内容如下
i love girl!
a beatiful girl is duoduo.
i love duoduo.
hi girl,
hi duoduo
are you ok?

从第一行开始查找文件,直到遇到含有 duoduo 字样的行为止
[beyes@localhost ~]$ sed -n '1,/duoduo/p' test.txt
i love girl!
a beatiful girl is duoduo.

如果继续匹配则继续打印
[beyes@localhost ~]$ sed -n '2,/duoduo/p' test.txt
a beatiful girl is duoduo.
i love duoduo.                #第四行已经不含有 duoduo ,故到第三行时终止
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|曲径通幽 ( 琼ICP备11001422号-1|公安备案:46900502000207 )

GMT+8, 2025-6-18 16:58 , Processed in 0.085045 second(s), 22 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表