Sed基础入门

参照:张昊著《LINUX Shell编程从入门到精通》,Richard Blum著《Linux命令行与shell脚本编程大全》

希望大家在学习前先看看正则表达式,正则表达式在Linux文本处理中会经常用到,这里不会介绍正则表达式。

【一、初识sed】

  1. sed是编辑器,是基于行的,按顺序对每一行执行命令。
  2. 命令选项:
    • -e script :    在处理输入时,将script中指定的命令添加到运行的命令中
    • -f file:    在处理输入时,将file中指定的命令添加到运行的命令中
    • -n:      不要主动输出,等待p输出命令时才输出
  3. 要在命令行上执行多个命令,要用-e选项,命令之间用 ; 分隔
    • 如:sed  –ne   ‘=; p’   /etc/passwd
  4. 要读取文件中的sed命令,使用-f选项
    • image
  5. 如上图中,s代表替换命令,找到bash并用mysh替换,找到包含gr的行打印出来,可以看到,/bin/bash已被修改为/bin/mysh

 

【二、sed编辑器基础】

  1. 删除(d)
    • 对匹配的行进行删除操作
      • sed ‘2d’ data        删除第2行
      • sed ‘2,$d’  data    删除第2行到尾行
  2. 替换(s)
    • 替换标记:
      • 形式:s/pattern/replacement/flags
      • flags
        • 数字:表明新文本将替换一行中第几处模式匹配的地方
        • g:   全局替换
        • p:   将模式匹配的行替换后的内容打印出来
          • image
        • w file:  将模式匹配的行替换后的内容写入file文件
          • image
    • 替换字符
      • 有时文本中存在一些文本字符不方便在替换模式中使用,如文本中的/,和分隔符的/相同,两种方法解决:
        • 对文本中出现的/进行转义,如:
          sed 's/\/bin\/bash/\/bin\/csh/' /etc/passwd
        • 使用其它字符来替代/分隔符
          sed 's:/bin/bash:/bin/csh' /etc/passwd
  3. 使用地址
    • 数字方式的行寻址
      • sed   ‘2d’ /etc/passwd  删除第二行
      • sed   ‘2,5d’ /etc/passwd  删除第2到5行
      • sed   ‘2,$s/gr/mygr/g’ /etc/passwd   从第2行到最后一行把所有gr换成mygr
    • 正则过滤行
      • sed   -n  ‘/gr/p’        查找有gr的行并输出
    • 组合命令
      • 有时需对匹配到的行执行多条命令,用{}括起来
        • sed ‘2{s/fox/elephant/; s/dog/cat/} data    对第2行执行两条替换命令
    • 若没有地址匹配,则是对每行都进行处理
  4. 插入(i)
    • 在指定行前增加一个新行,形式:sed ‘[address]command\”new line”’
      • echo “Test Line 2” | sed ‘i\Test Line 1’
  5. 附加(a)
    • 同插入命令,只是在指定行之后增加一行
      • echo “Test Line 2” | sed ‘a\Test Line 2’
      • sed ‘$a\this is append line ‘ data
      • 若添加多行,需要在每行后面都增加\
        • sed ‘$a\
          • this is the second line\
          • this is the last line’    data
          • image
  6. 修改(c)
    • 和插入,附加命令相似,只是修改指定行的内容
      • sed ‘$c\
        • this is the changed line.’ data             将最后一行的内容改为this is the changed line.
  7. 转换(y)
    • 唯一可以处理单个字符的sed编辑器命令,形式:[address]y/inchars/outchars/
      • sed ‘$y/abc/ABC/’  data          把a换成A,b换成B,c换成C
  8. 打印
    • 打印行
      • sed –n ‘3p’       打印第3行
    • 打印行号
      • sed ‘=’data      在行的上面插入一行表示行号
    • 列出行(l)
      • 打印不可见字符,如用\t代表制表符
  9. 写入(w)
    • 使用w命令进行保存
      • sed ‘3w data_bak’  data 将data中的第3行写入data_bak中
  10. 读取(r)
    • 使用r命令读取文件,会在指定行后面插入文件中的所有内容,形式[address]r filename
      • 不能指定范围地址,因为它要在指定一行后面插入
      • 如果想用文件中的内容替换指定行,而不是添加在该行后面,只需在最后删除该行:
        • sed ‘${r
          • /etc/passwd
          • d
          • }’data                             在data文件尾行插入/etc/passwd内容,并删除尾行

 

【三、sed进阶】

  1. 这里先给一个经典的例子,去除html标签,只显示其中的文本
    • 这里,只需要将<>标签删除即可,如:<title>this is test page</title>
      • 读者也许会用 sed ‘s/<.*>//g’ index.html 去处理,   .* 会匹配任意多个字符
      • 但sed采用的最长匹配,已就是说,它会找到后面的</title>中的>,所有这一行都会被删除(包括文本内容)
    • 为了避免这种问题,这里匹配的时候要确保< >中间没有>,所有命令如下:
      • sed ‘s/<[^>]*>//g’ index.html  ,这样的话,遇到<title>中的>就会匹配结束,删除该<title>标签,同理,匹配删除</title>
  2. 多行命令
    • next命令
      • 小写n:  移动数据流到下一行
      • 大写N:  将下一行加入当前行处理
        • sed ‘/first/{N; s/\n//g}’ data
    • 多行删除命令,D只会删除多行中的第一行,删除第一行包括\n,并且回环到脚本的起始处
      • 删除首行空白行,已知第2行含header单词
      • sed ‘^${N;/header/D}’data   首先会查找空白行,然后加入下行,判断是否存在headder,若存在,则删除第一行
    • 打印多行,P只会打印多行中的第一行
  3. 保持空间
    • 模式空间是一块活动缓冲区,利用保持空间来临时保存一些行
      • h 将模式空间复制到保持空间
      • H 将模式空间附加到保持空间
      • g 将保持空间复制到模式空间
      • G 将保持空间附加到模式空间
      • x 交换模式空间和保持空间的内容
    • sed –n ‘/first/{
      • h
      • p
      • n
      • p
      • g
      • p
      • }’ data
      • h 先将含有first行放到保持空间,p打印模式空间
      • n 移动到下一行,p打印模式空间
      • g 将保持空间放到模式空间,即刚才含first的行,并打印模式空间
  4. 排除命令
    • 使用!排除命令,让原本起作用的命令不起作用
      • sed –n ‘/first/!p’  data  本来是只打印含有first行;现在正好相反,含有first行的不会打印,其它行都打印
    • 反转数据流文本行的顺序,先输出最后一行,最后输出第一行
      1. 在模式空间放置1行
      2. 先将模式空间的1行放到保持空间
      3. 在模式空间放入下一行
      4. 将保持空间内容附加到模式空间 (G 命令)
      5. 将模式空间内容放到保持空间  (h 命令)
    • 注意,第1行不要进行G操作,最后一行进行打印操作
    • sed –n ‘1!G; h; $p’ data
  5. 改变流
    • 跳转(b),对命令进行跳转,执行指定命令,形式如下:[address] b [label]
      • address参数决定了哪行数据触发跳转命令,若label未指定,则默认跳转到命令脚本结尾
      • sed ‘{2,3b; s/dog/cat/; s/head/tail/}’ data       在2,3行触发跳转到最后,不执行替换命令
      • sed –n ‘{:start; s/,//1p; /,/b start}’data            如果有,则跳到start,并替换,
    • 测试(t),基于替换命令跳转到下一个标签,而不是基于地址跳转到一个标签
      • sed ‘{s/first/matched/; t; s/hello/world/}’  data   
      • 查找first,如果匹配了选中的模式,测试命令会跳过后面替换命令,如果,第一个命令没有匹配,第二个命令就会被执行。
  6. 模式替代
    • and(&)符号
      • echo “the cat sleeps in his hat.” | sed ‘s/.at/”&”/g’      用&代替前面匹配的项,如cat,hat
    • 替换单独的单词,使用小括号
      • sed “that furry cat is pretty” | sed ‘s/furry \(.at\)/\1/’        that cat is pretty
      • 用\1代替前面小括号里匹配的单词,小括号加\,说明为聚合字符,而不是普通的小括号
posted @ 2013-06-11 23:21  bairuiworld  阅读(974)  评论(0编辑  收藏  举报