文本处理工具——sed

事前说明一下,有的时候我可能用m1,有时候有用了/data/m1,其实这两个在这篇文章里是一个意思,前面是相对路径表示,后面是绝对路径。不好意思,正在努力改掉这个坏习惯,以后在一篇文章里尽量保持一致。

简介

  1. Stream EDitor, 行编辑器
  2. sed是一种流编辑器,它一次处理一行内容。处理时,把当前处理的行存储在临时
    缓冲区中,称为“模式空间”(pattern space),接着用sed命令处理缓冲区中的
    内容,处理完成后,把缓冲区的内容送往屏幕。然后读入下行,执行下一个循环。
    如果没有使诸如‘D’ 的特殊命令,那会在两个循环之间清空模式空间,但不会清
    空保留空间。这样不断重复,直到文件末尾。文件内容并没有改变,除非你使用重
    定向存储输出
  3. 功能:主要用来自动编辑一个或多个文件,简化对文件的反复操作,编写转换程序等
  4. 参考: http://www.gnu.org/software/sed/manual/sed.html

用法

    1.在option可以选择也可不选择加入选项,常见选项的有:

  • 格式:sed [option]... 'script' filepath...  
  • -n :不输出模式空间的内容到屏幕,即不自动打印。(PS:sed会默认打印模式空间的内容,使用-n可以避免重复打印)
  • -e :多点编辑
  • -r  :支持扩展正则表达式
  • -i.bak :先对文件进行备份再进行原处编辑 (sed -i就意味着直接对文件进行修改,所以还是sed -i.bak保险,先备份)

     2.1  'script' 是地址命令,简言之就是在单引号里加入地址定界和编辑命令

 

  • 地址定界:分四种情况。
  • (1)不给地址:那么sed就会对全文进行处理,比如sed  ''  /data/m1结果就是将m文件中的内容全部打印到屏幕
  • (2)单地址,这个时候地址定界后面就要接编辑命令了。
  • #:指定第#行。比如sed '2p' /data/m1,(p是打印当前模式空间内容,追加到默认输出之后)此时结果是m1文件中内容全部被打印出来,但是第2行被打印两次,要是想取消默认打印,-n了解一下。
  • $:指定最后一行,用法同上一条。
  • /pattern/:匹配与pattern相似的行

 

  • (3)地址范围:可以指定范围来匹配
  • #,#    匹配第#行到第#行的内容,演示如下,显示第一行到第三行的内容,这里我忘记加-n了,所以sed又默认打印了一遍。 

 

  • #1,+#   匹配第#1行到第#1+#行的内容,比如'1,+2'就是第一行到第三行,以此类推。注意sed不识别类似'3,-1'这样的写法。
  • /partern1/,/partern2/   sed还支持对两个模式范围内进行操作。

  • #,/partern1/  指定行号和模式进行操作

  •  (4)~:步进
  • 举个栗子:1~2表示从第一行开始,每隔两行进行显示,可以理解为只显示奇数行。
  • 那么2~2就是从第二行开始每隔两行显示,即显示偶数行。

 前面说到'script'分为两部分,地址定界和编辑命令。下面介绍一下编辑命令。

2.2 编辑命令

 

把he全部替换成ppppp

         这个时候加上g就可以了

  • d:删除模式空间匹配的行,并立即启用下一轮循环。emmmmm,简单理解就是删除指定行,不让它显示了。但这只是删除模式空间匹配的行,真实文件里内容并未被删除。只有选项选择i才会修改。
  •  p:打印当前模式空间内容,追加到默认输出之后。之前用到过,值得注意的是sed本身默认会打印,加上p之后如果没有其它命令的话就会打印两次。
  • a [\]text:在指定行后面追加文本,支持使用\n实现多行追加,不光是换行,这里\是告诉计算机\以后都是要加入的内容。(PS:本来学到的是用\符号,但是我手欠又试了一下/符号,居然也阔以)
  • i [\]text:在行前面插入文本,用法同上一条。
  • c [\]text:替换行为单行或多行文本,用法同上一条。
  • w /path/somefile: 保存模式匹配的行至指定文件。举个栗子^_^,
    sed '/th/w /data/m3' /data/m1

    从m1文件中匹配包含th的行,并把该行写到m3文件中,m3不用事先创建,这里自动创建并写入。

  • r /path/somefile:读取指定文件的文本至模式空间中匹配到的行后,跟上一条用法相似。
  • =: 为模式空间中的行打印行号
  • !:模式空间中匹配行取反处理。
  • s///:查找替换,支持使用其它分隔符,s@@@,s###
  • 替换标记:
  • ①g: 行内全局替换。一行可能出现多个匹配的字符,如果仅仅用s///就会出现只替换前面出现的字符而后面的则不会替换。
  • ②p: 显示替换成功的行
  • ③w /PATH/TO/SOMEFILE:将替换成功的行保存至文件中。

当然,本文所用的文件内容很简单,其实实际中遇到的文件很复杂,要精确匹配并修改还需要扎实的正则表达式基础。咳咳,这是题外话。

   3. 高级编辑命令

模式空间与保持空间:都在内存里,保持空间用来放置模式空间里未处理完的内容。

  • P(大写) :打印模式空间开端至\n内容,并追加到默认输出之前
  • h :把模式空间中的内容覆盖至保持空间中
  • H:把模式空间中的内容追加至保持空间中
  • g :从保持空间取出内容覆盖至模式空间
  • G:从保持空间取出数据追加至模式空间
  • d :删除模式空间中的行
  • D:如果模式空间包含换行符,则删除直到第一个换行符的模式空间中的文本,并不会读取新的输入行,而使用合成的模式空间重新启动循环。如果模式空间不包含换行符,则会像发出d命令那样启动正常的新循环(举个栗子:模式空间里有三行数据,那D就只删除第一行的,d是全删除)
  • n :读取匹配到的行的下一行覆盖至模式空间
  • N:读取匹配到的行的下一行追加至模式空间
  • x :把模式空间中的内容与保持空间中的内容进行互换

 看看能不能猜到下面的命令含义

sed -n 'n;p' FILE
sed '1!G;h;$!d' FILE
sed‘N;D’ FILE
sed '$!N;$!D' FILE
sed '$!d' FILE
sed ‘G’ FILE
sed ‘g’ FILE
sed ‘/^$/d;G’ FILE
sed 'n;d' FILE
sed -n '1!G;h;$p' FILE


再附一道练习题
利用sed 取出ifconfig命令中本机的IPv4地址。
 

ifconfig ens33|sed -n '2p'|sed -nr 's/.*inet[[:space:]](.*)[[:space:]]netmask.*/\1/p'

或者

查询centos7版本的
ifconfig ens33|sed '2!d'|sed -r -e 's/^[[:space:]].*inet//' -e 's/[[:space:]].*//'
ifconfig ens33|sed -n '2p'|sed -r 's@(.*inet[[:space:]](.*)([[:space:]]netmask.*)@\2@'
ifconfig ens33|sed -n '2p'|sed -r 's@.*inet[[:space:]](.*)[[:space:]]netmask.*@\1@'
centos6版本
ifconfig eth0|sed -n '2p'|sed -r 's/.*addr:(.*)Bcast.*/\1/'

三选一。 6和7版本的ip地址格式不同,细节可以自己发现。

勤能补拙,多练。

猜你喜欢

转载自blog.csdn.net/qq_39155877/article/details/81480322