sed入门实例

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了sed入门实例相关的知识,希望对你有一定的参考价值。

语法格式

     

sed [-nefir] ‘command‘ file(s) 

sed [-nefir] -f scriptfile file(s) 

常用选项

        -n∶使用安静(silent)模式。在一般 sed 的用法中,sed在所有的脚本指令执行完毕后,将自动打印模式空间中的内容到屏幕上。但如果加上 -n 参数后,则只有经过sed 特殊处理的那一行(或者动作)才会被列出来。

        -e∶直接在指令列模式上进行 sed 的动作编辑;

        -f∶直接将 sed 的动作写在一个档案内, -f filename 则可以执行 filename 内的sed 动作;

        -r∶sed 的动作支援的是延伸型正规表示法的语法。(预设是基础正规表示法语法)

        -i∶直接修改读取的档案内容,而不是由萤幕输出。       


常用指令:

名称 命令 语法 说明
替换 s [address]s/pattern/replacement/flags 替换匹配的内容
删除 d [address]d 删除匹配的行
插入 i [line-address]i\

text
在匹配行的前方插入文本
追加 a [line-address]a\

text
在匹配行的后方插入文本
行替换 c [address]c\

text
将匹配的行替换成文本text
打印行 p [address]p 打印在模式空间中的行
打印行号 = [address]= 打印当前行行号
打印行 l [address]l 打印在模式空间中的行,同时显示控制字符
转换字符 y [address]y/SET1/SET2/ 将SET1中出现的字符替换成SET2中对应位置的字符
读取下一行 n [address]n 将下一行的内容读取到模式空间
读文件 r [line-address]r file 将指定的文件读取到匹配行之后
写文件 w [address]w file 将匹配地址的所有行输出到指定的文件中
退出 q [line-address]q 读取到匹配的行之后即退出


待需要处理的文本test.txt内容如下:

DEVICE=eth1
HWADDR=00:0c:29:c5:ae:ed
TYPE=Ethernet
UUID=bb4e221b-6953-4bfd-9842-fd442c02ae8e
ONBOOT=yes
NM_CONTROLLED=yes
BOOTPROTO=dhcp
DNS1=202.96.18.166
IPV6INIT=no
USERCTL=no
PEERDNS=yes

sed选项

   a 追加:

例子

在第三行后面增加一行,内容为ipv4=192.168.1.1

   sed ‘3a ipv4=192.168.1.1‘ test.txt

结果

DEVICE=eth1
HWADDR=00:0c:29:c5:ae:ed
TYPE=Ethernet
ipv4=192.168.1.1
UUID=bb4e221b-6953-4bfd-9842-fd442c02ae8e
ONBOOT=yes
NM_CONTROLLED=yes
BOOTPROTO=dhcp
DNS1=202.96.18.166
IPV6INIT=no
USERCTL=no
PEERDNS=yes

   i 插入:

例子

在第三行前面增加一行,内容为ipv4=192.168.1.1

   sed ‘3i ipv4=192.168.1.1‘ test.txt

结果

DEVICE=eth1
HWADDR=00:0c:29:c5:ae:ed
ipv4=192.168.1.1
TYPE=Ethernet
UUID=bb4e221b-6953-4bfd-9842-fd442c02ae8e
ONBOOT=yes
NM_CONTROLLED=yes
BOOTPROTO=dhcp
DNS1=202.96.18.166
IPV6INIT=no
USERCTL=no
PEERDNS=yes

   s 替换:

例子

将所有的yes改为NO

    sed ‘s/yes/NO/g‘ test.txt

结果

DEVICE=eth1
HWADDR=00:0c:29:c5:ae:ed
TYPE=Ethernet
UUID=bb4e221b-6953-4bfd-9842-fd442c02ae8e
ONBOOT=NO
NM_CONTROLLED=NO
BOOTPROTO=dhcp
DNS1=202.96.18.166
IPV6INIT=no
USERCTL=no
PEERDNS=NO

例子

在每行行首加上#

    sed ‘s/^/#&/g‘ test.txt

结果

#DEVICE=eth1
#HWADDR=00:0c:29:c5:ae:ed
#TYPE=Ethernet
#UUID=bb4e221b-6953-4bfd-9842-fd442c02ae8e
#ONBOOT=yes
#NM_CONTROLLED=yes
#BOOTPROTO=dhcp
#DNS1=202.96.18.166
#IPV6INIT=no
#USERCTL=no
#PEERDNS=yes

在每行行尾加上#

    sed ‘s/$/&#/g‘ test.txt

结果

DEVICE=eth1#
HWADDR=00:0c:29:c5:ae:ed#
TYPE=Ethernet#
UUID=bb4e221b-6953-4bfd-9842-fd442c02ae8e#
ONBOOT=yes#
NM_CONTROLLED=yes#
BOOTPROTO=dhcp#
DNS1=202.96.18.166#
IPV6INIT=no#
USERCTL=no#
PEERDNS=yes#



除了第三行外,所有行的末尾加上#

[[email protected] ~]# sed ‘3! s/$/&#/g‘ test.txt
DEVICE=eth1#
HWADDR=00:0c:29:c5:ae:ed#
TYPE=Ethernet
UUID=bb4e221b-6953-4bfd-9842-fd442c02ae8e#
ONBOOT=yes#
NM_CONTROLLED=yes#
BOOTPROTO=dhcp#
DNS1=202.96.18.166#
IPV6INIT=no#
USERCTL=no#
PEERDNS=yes#

排除IPV6所在的行,其他行行尾加上#

[[email protected] ~]# sed ‘/IPV6/!s/$/&#/g‘ test.txt
DEVICE=eth1#
HWADDR=00:0c:29:c5:ae:ed#
TYPE=Ethernet#
UUID=bb4e221b-6953-4bfd-9842-fd442c02ae8e#
ONBOOT=yes#
NM_CONTROLLED=yes#
BOOTPROTO=dhcp#
DNS1=202.96.18.166#
IPV6INIT=no
USERCTL=no#
PEERDNS=yes#




高级应用

p和P

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

P:打印当前模式空间开端至\n的内容,并追加到默认输出之前;

n和N

n:n命令简单来说就是提前读取下一行,覆盖模型空间前一行(并没有删除,因此依然打印至标准输出),如果命令未执行成功(并非跳过:前端条件不匹配),则放弃之后的任何命令,并对新读取的内容,重头执行sed。


n处理流程如下:


例子

[[email protected] ~]# cat num.txt
1
2
3
4
5


例子

[[email protected] ~]# cat num.txt
1
2
3
4
5

打印偶数行


sed -n ‘n;p‘ num.txt
2
4

解析:

读取1到模式空间

执行命令n

读取2并覆盖到模式空间

执行命令p

输出2


立即执行下一循环

读取3到模式空间

执行命令n

读取4并覆盖到模式空间

执行命令p,过程如下

输出4

最后一行,5的具体过程如下


读取5进模式空间


运行命令n,不过读取不到下一行


因为读不到,所以sed退出所有的命令


已经是文件尾,sed结束运行。 



打印机奇数行

sed -n ‘$!N;P‘ num.txt
1
3
5

解析

读取1,$!条件满足(不是尾行),执行N命令,得出1\n2,执行P,打印得1,读取3,$!条件满足(不是尾行),执行N命令,得出3\n4,执行P,打印得3,读取5,$!条件不满足,跳过N,执行P,打印得5

d和D

d:删除当前模式空间内容(不在传至标准输出),并放弃之后的命令,并对新读取的内容,重头执行    sed。

D:删除当前模式空间开端至\n的内容(不在传至标准输出),放弃之后的命令,但是对剩余模式空间重  新执行sed。

[[email protected] ~]# cat num.txt
1
2
3
4
5

打印奇数行

[[email protected] ~]# sed ‘n;d‘ num.txt
1
3
5

解析:

读取1,执行n,打印1至标准输出,得出2,执行d,删除2,得空,以此类推,读取3,执行n,打印3至标准输出,得出4,执行d,删除4,得空,但是读取5时,因为n无法执行,所以d不执行。因无-n参数,故输出1\n3\n5;


读取文本的最后一行

[[email protected] ~]# sed ‘N;D‘ num.txt
5

注释:读取1,执行N,得出1\n2,执行D,得出2,执行N,得出2\n3,执行D,得出3,依此类推,得出5,执行N,条件失败退出,因无-n参数,故输出5

注意:

d命令在运行后会直接执行下一循环,所以它并不会执行之后的命令和打印模式空间;例如:在d命令后使用a----将不执行。

[[email protected] ~]# sed ‘n;d;a----‘ num.txt
1
3
5

h和H g和G


h:将当前模式空间中内容覆盖至保持空间

H:将当前模式空间中的内容追加至保持空间

g:将当前保持空间中内容覆盖至模式空间

G:将当前保持空间中的内容追加至模式空间


例子

[[email protected] ~]# cat num.txt
1
2
3
4
5

单独使用h

[[email protected] ~]# sed  ‘h‘ num.txt
1
2
3
4
5

将当前的内容复制到保持空间,默认只输出模式空间的内容;

[[email protected] ~]# sed  ‘G‘ num.txt
1

2

3

4

5

将保持空间的内容追加到当前模式空间;由于保持空间是空的;因此追加的结果是在每行的后面添加一个空行;


例子


将所有行倒数输出

[[email protected] ~]# sed ‘1!G;h;$!d‘ num.txt
5
4
3
2
1

解析:

  读取第一行;匹配1!G,因此不会把保持空间的内容复制到模式空间,当前内容为1;执行h,第一行的内容(1)放到保持空间;执行$!d不是最后一行,删除模式空间内容;

第一行执行后结果:模式空间内容为空,保持空间内容1(如图)

技术分享

读取第二行,执行1!G,匹配1!G,将保持空间追加到模式空间

技术分享

执行h复制模式空间的内容放到保持空间

技术分享


执行$!d不是最后一行,删除

技术分享


读取第三行,执行1!G,匹配1!G,将保持空间追加到模式空间

技术分享

执行h复制模式空间的内容放到保持空间

技术分享

执行$!d不是最后一行,删除

技术分享

读取第四行,执行1!G,匹配1!G,将保持空间追加到模式空间

技术分享

执行h复制模式空间的内容放到保持空间

技术分享

执行$!d不是最后一行,删除

技术分享

读取最后一行,执行1!G,匹配1!G,将保持空间追加到模式空间

技术分享

执行h复制模式空间的内容放到保持空间

技术分享

因为是最后一行,不执行$!d;结果如下

[[email protected] ~]# sed ‘1!G;h;$!d‘ num.txt
5
4
3
2
1


例子

[[email protected] ~]# cat num.txt
1
2
3
4
5

在倒数第二行加上“;”

[[email protected] ~]# sed ‘$!N;$!P;$!D;s/\(\n\)/;\n/‘ num.txt 
1
2
3
4;
5

解析:

第一行1读入,匹配$!N;变成1\n2,

匹配$!P;变成

1

1\n2

匹配$!D

变成

1

2

由于没有\n;因此s/\(\n\)\;\n/这一条不执行;

第二次读入,匹配$!N;变成

1

2\n3

匹配$!P;变成

1

2

2\n3

匹配$!D

变成

1

2

3

第三次读入,匹配$!N;变成

1

2

3\n4

匹配$!P;变成

1

2

3

3\n4

匹配$!D

变成

1

2

3

4

第三次读入,匹配$!N;变成

1

2

3

4\n5

不匹配$!P;因此不执行

不匹配匹配$!D

匹配到s/\(\n\)/;\n/ 因此后面变加了“;”

sed ‘$!N;$!P;$!D;s/\(\n\)/;\n/‘ num.txt 


替换 s [address]s/pattern/replacement/flags 替换匹配的内容
删除 d [address]d 删除匹配的行
插入 i [line-address]i\

text
在匹配行的前方插入文本
追加 a [line-address]a\

text
在匹配行的后方插入文本
行替换 c [address]c\

text
将匹配的行替换成文本text
打印行 p [address]p 打印在模式空间中的行
打印行号 = [address]= 打印当前行行号
打印行 l [address]l 打印在模式空间中的行,同时显示控制字符
转换字符 y [address]y/SET1/SET2/ 将SET1中出现的字符替换成SET2中对应位置的字符
读取下一行 n [address]n 将下一行的内容读取到模式空间
读文件 r [line-address]r file 将指定的文件读取到匹配行之后
写文件 w [address]w file 将匹配地址的所有行输出到指定的文件中
退出 q [line-address]q 读取到匹配的行之后即退出

本文出自 “请你给我一把刀” 博客,请务必保留此出处http://lulucao2006.blog.51cto.com/5375246/1754721

以上是关于sed入门实例的主要内容,如果未能解决你的问题,请参考以下文章

sed常用选项的简单介绍

Linux常用命令——sed

Linux- 系统随你玩之--文本处理三剑客--grep继任者sed

linux零基础学习之Linux sed 命令常用操作详解

shell中的sed用法

sed修炼系列:花拳绣腿之入门篇