文本处理工具sed

来源:互联网 发布:卡尔波普尔 知乎 编辑:程序博客网 时间:2024/05/16 02:20

文本处理工具有好多种,上次介绍了grep,这次介绍一下sed。sed全名stream editor,意为行编辑器,或者流编辑器。Sed是逐行进行编辑的,下面介绍常规用法和高级用法。

格式:sed [option] 'script' inputfile sed加选项,单引号里是要执行的一些操作,后面跟操作的对象,常常是文件或者脚本文件。

一、选项

-n 不输出模式空间内容到屏幕,即不自动打印

-e: 多点编辑,对每行处理时,可以有多个Script

-f: 把Script写到文件当中,在执行sed时-f 指定文件路径,如果是多个Script,换行写

-r: 支持扩展的正则表达式

-i: 直接将处理的结果写入文件

-i文件名 在将处理的结果写入文件之前备份一份

上面这些选项常常用作地址定界,下面举例说明它们的用法。

  1. 不给地址:对全文进行处理

    sed ' ' 这里没有给定具体范围,输入什么就输出什么,sed默认打印输出,如在屏幕输入a,回车之后默认输出a,相当于输出两遍

    sed -n ' '这里加-n就是把默认输出到屏幕的给去掉,不显示默认值,如在屏幕输入a,就会打印a,但是不显示默认的,所以相当于输出一遍

  2. 单地址:

    先给个文件供参考:

    假如上面的是文件a.txt的内容,下面基于这个内容来做实验。

    sed '2p' a.txt 这里2的意思是第二行,p的意思是打印输出,这就话就是说把名为a.txt的文件的第二行的内容打印输出到屏幕,但是由于sed默认会打印一遍,所以结果是第二行输出了两遍。

    sed -n '2p' a.txt 和上面的差不多,但是这里加了-n,-n就是不输出默认的,所以这里意思就是只显示第二行的内容

     

    sed -n '/a/p' a.txt 这里也是一个单地址界定,/a/意思就是取有字母a的行 ,这个命令的意思就是把有a的行打印出来

  3. 地址范围:

    sed '2,3p' a.txt 这里2,3的意思就是一个范围定界啦,意为2到3行,p是打印输出,所以这个命令的意思就是把2到3行的内容打印出来,这里默认没有去掉,所以会把所有的都打印一遍,然后2到3行的会多打印一遍。

    sed -n '2,3p' a.txt 和上面的意思一样,加-n意思就是只打印2到3行,其他的不输出

    sed -n '2,+1p' a.txt 这里'2,+1p'意思是输出2到2+1行的内容,也就是第二行到第三行的内容,和上面意思差不多,只不过换了一种表示方法。

    sed -n '/dog/,/mouse/p' b.txt '/dog/,/mouse/p'意思是把有dog的行到有mouse的行的内容截取出来

    先看一下b.txt的内容

    再看运行命令的结果

    sed -n '2,/desk/p' c.txt '/2,/desk/p' 意思是把第二行到有desk的行的内容输出出来

    先看一下c.txt的内容

    运行上面的命令后结果为

  4. ~步进

    sed -n '1~2p' c.txt '1~2p'意思就是输出奇数行的内容 ,若第一个为1,第二个就为3,第三个就是5,一次加2,所以整体的意思就是输出1,3,5,7,…..行的内容了。

二、编辑命令

d: 删除模式空间匹配的行,并立即启用下一轮循环

    举例:sed '2d' d.txt '2d'就是把第二行的内容从文件中删除

p:打印当前模式空间内容,追加到默认输出之后

    举例: sed -n '2p' d.txt '2p'输出第二行的内容,加-n,只输出第二行的内容

a [\]text:在指定行后面追加文本,支持使用\n实现多行追加

    举例:sed '2a\123' c.txt '2a\123' 就是在第二行的后面加上一行内容为123

i [\]text:在行前面插入文本

    举例:sed '2i\123' c.txt '2i\123'就是在第二行的前面加上一行内容为123

c [\]text:替换行为单行或多行文本

    举例:sed '2c\123' c.txt '2c\123' 就是把第二行的内容替换为123

w /path/somefile: 保存模式匹配的行至指定文件

    举例:sed '2w/root/bin/pets' d.txt '2w/root/bin/pets' 意思就是把第二行的内容保存到/root/bin/pets,w就是写的意思

r /path/somefile:读取指定文件的文本至模式空间中匹配到的行后

    举例:sed '2r/root/s.txt' d.txt '2r/root/s.txt'意思就是把文件s.txt的内容保存到d.txt的第二行的后面,r就是读的意思

=: 为模式空间中的行打印行号

    举例:sed '=' c.txt 意思就是给文件c.txt每行打上行号

!:模式空间中匹配行取反处理

    举例:sed -n '2!p' d.txt '2!p'意思就是不显示第二行,其他的都输出,加上-n就是不显示默认,总的意思就是显示文件内容一遍,除了第二行。

s///:查找替换,支持使用其它分隔符,s@@@,s###替换标记:

g: 行内全局替换

    举例:sed 's/dog/miaomiao/g' c.txt 把文件c.txt中的dog替换成miaomiao,g是全局替换。

三、日常练习

1、删除centos7系统/etc/grub2.cfg文件中所有以空白开头的行行首的空白字符

解题思路 :sed 是 支持正则表达式的,所以在这里可以引用。Sed –r 就是支持扩展正则表达式,^[[:space:]]是以空白开头,在这里可以使用替换思想,把以空白开头的替换为无,就相当于删除了空白 ,所以本题使用替换的方法。

答:cat /etc/grub2.cfg |sed -r 's/^[[:space:]]+//'

2、删除/etc/fstab文件中所有以#开头,后面至少跟一个空白字符的行的行首的#和空白字符

解题思路:和第一题思路很像,^#就是以#开头,[[:space:]]+就是至少一个空白字符,+就是至少一个的意思,在扩展正则表达式中,不用加\,本题同样采用替换的思想,把以#开头,后面….替换为无就可以了,相当于删除了。

答:cat /etc/fstab|sed -r 's/^#[[:space:]]+//'

3、在centos6系统/root/install.log每一行行首增加#号

解题思路:^就代表行首的意思,使用替换思想,把行首替换为#就是本题解题思路。

答题:cat /root/install.log|sed 's/^/#/'

4、在/etc/fstab文件中不以#开头的行的行首增加#号

解题思路:^[^#]表示以非#开头的,也就是不以#开头,#&就是增加#的意思,这里使用了后向引用和替换的思想。

答题:cat /etc/fstab |sed 's/^[^#]/#&/'

5、处理/etc/fstab路径,使用sed命令取出其目录名和基名

解题思路:使用替换思想,可以看到目录名就是/etc/,就是以/开头的,最后跟着个/的,所以在这里我们就先把目录名给提取出来,^/.*/意思就是以/开头,中间有任意内容,后面有/,下面提取基名,可以看到基名是不以/开头的,但可以以/结尾的,所以这里就是[^/].*/?$,[^/]不以/开头,.*任意内容,/?$以0或者一个/结尾,我们把基名和目录名已经截取出来了,接着使用后向引用,就可以直接提取基名和目录名了。\1引用第一个括号中的内容,\2引用第二个括号里的内容。

答题:echo /etc/fstab |sed -r 's#(^/.*/)([^/].*/?$)#\1\n\2#'

四、高级编辑命令

前面都是一些简单的选项和命令,现在来点有难度的。Sed高级编辑命令如下:

h: 把模式空间中的内容覆盖至保持空间中

H:把模式空间中的内容追加至保持空间中

g: 从保持空间取出数据覆盖至模式空间

G:从保持空间取出内容追加至模式空间

x: 把模式空间中的内容与保持空间中的内容进行互换

n: 读取匹配到的行的下一行覆盖至模式空间

N:读取匹配到的行的下一行追加至模式空间

d: 删除模式空间中的行

D:删除当前模式空间开端至\n的内容(不再传至标准输

出),放弃之后的命令,但是对剩余模式空间重新执行sed

举例说明:

  1. sed -n 'n;p' FILE

    解释:n读取匹配到的行的下一行覆盖至模式空间, p输出。意思就是开始读第一行内容到模式空间,然后第二行内容把第一行内容覆盖掉,输出第二行,然后读第三行内容到模式空间,再然后第四行内容把第三行内容覆盖,输出第四行,后面依次循环,可以想到输出的都为偶数行,所以这条命令的意思就是输出偶数行。

    如下所示:输入7个数字,结果只输出了2,4,6,都是偶数。

  2. sed '1!G;h;$!d' FILE

    解释:1!当不是第一行的时候,G从保持空间取出内容追加至模式空间,h把模式空间中的内容覆盖至保持空间中,$!不是末尾的时候,d删除,这些命令连起来就是说 先看是不是第一行,是的话跳过第一个分号,执行第二个分号命令,不是的话就从保持空间取出内容追加至模式空间,现在先说从第一行执行的过程,首先判断是第一行,然后跳过第一个分号,执行第二个分号内容h,假设第一行数据为1,h执行后模式1覆盖到保持空间,同时模式空间还有1,记住,是覆盖而不是转移,接着执行第三个分号内容,1肯定不是结尾,所以执行删除命令,把模式空间中的1删除,现在只剩保持空间还有一个1,第一遍循环已经结束,接着执行第二遍循环,多都市一样的,这里我就不多说了,相信大家自己会判断的。这条命令的意思就是逆序输出。

    如下所示:

  3. sed -n '1!G;h;$p'

    解释:先判断是否为第一行,是的话跳过第一个分号,执行第二个分号的命令,不是的话从保持空间取出内容追加至模式空间,接着依次往下执行,h把模式空间中的内容覆盖至保持空间中,$p判断时是否为结尾,是的话输出。这条命令意思也是逆序输出。

    如下所示

  4. seq 7 |sed 'n;d'

    解释:n读取匹配到的行的下一行覆盖至模式空间,d删除,先把第一行内容输出到模式空间,然后读取第二行内容,接着执行d把第二行的内容删除,输出第一行内容到屏幕,接着读取第三行内容到模式空间,读取第四行内容,再把第四行内容删除,后面依次循环,可以想到输出到屏幕的是1,3,5,….奇数行,所以这条命令的意思就是输出奇数行。

    如下所示:

原创粉丝点击