文本处理三剑客之sed基础用法

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了文本处理三剑客之sed基础用法相关的知识,希望对你有一定的参考价值。

    sed简介:

        sed是Stream EDitor的缩写,也就是流编辑器的意思,准确的说sed是一个交互式的面向字符流的编辑器,这是因为输入的数据通过sed程序并直接输出到标准输出(可以是显示器或者文件)。

    sed功能:

        每次从文件中读取一行通过解释脚本指定的执行动作来处理这一行(一行要历经所有处理动作),然后开始下一行,直到结束。执行动作可以是多个(用;隔开每个动作),解释脚本也可以是多个,可以实现删除,插入,查找替换等等强大功能,但是一般不编辑源文件,也就是说源文件内容不发生变化。

    sed原理:

        sed每读取一行就会放到一个叫“模式空间”的空间中处理,然后默认输出到标准输出,注意

sed是行编辑器,每次只处理一行,处理完了一行才会继续处理下一行。当一行能被模式空间里的模式匹配就会执行你所指定的执行动作,当然默认也是会输出到标准输出,当这一行没被模式空间里的模式匹配到时候就直接输出到标准输出,正因为是通过模式空间来处理,所以不会直接编辑源文件。

    sed用法:

        sed [option] ‘script‘ input(处理option其他都是必须的)

        option:

                -n:将模式空间中默认输出到标准输出的强行不输出

                -e:实现多点操作,也就是可以一次指定多个script

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

                -i:相当于直接编辑源文件(用之前要慎重)

         script:包括地址定界和处理动作且两者之间没有空格。

            地址定界:

                空地址:只有处理动作而没有任何的地址就是代表全文件

                单地址:

                    #:表示只处理文件的#这一行

                    /pattern/:表示处理pattern模式所匹配到的每一行

                地址范围:

                    #1,#2:表示处理#1和#2之间所有行,事实上sed在匹配到第一个地址的时候就开启了处理模式(编辑模式会好理解些),然后一直编辑包括这个地址的行后面的所有行,直到匹配到第二个地址的时候就关闭编辑模式。

                    #,/pattern/:处理文件的第#行开始的后面所有行直到匹配到pattern这个模式的时候结束编辑模式。

                    /pattern1/,/pattern2/:处理文件从匹配到的pattern1的行开始的后面所有行直到匹配到pattern2为止

                地址步进:

                    #1~#2:表示处理从#1开始的以#2为步进的后面的所有行,例如1~2,处理所有奇数行,2~2表示处理所有偶数行。

                编辑命令:

                    d:删除模式空间中匹配到的行(就是删除匹配到地址定界的行)

[[email protected] ~]# sed ‘1,10d‘ /etc/fstab
UUID=1ae437de-485a-4f2e-a1b1-4e3327ba6c8a /var                    xfs     defaults        0 0
UUID=7efc21b5-5de1-47c1-8f92-a5b6a0f7f6a0 swap                    swap    defaults        0 0

                    p:将模式空间中的匹配到的行的内容打印出来

[[email protected] ~]# sed ‘10p‘ /etc/fstab
#
# /etc/fstab
# Created by anaconda on Sat Mar 12 16:15:59 2016
#
# Accessible filesystems, by reference, are maintained under ‘/dev/disk‘
# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
#
UUID=2816cce5-45cb-4632-b4ef-d5360260af6c /                       xfs     defaults        0 0
UUID=d8644fab-df0d-436b-9845-6a2f79ad6f99 /boot                   xfs     defaults        0 0
UUID=d8644fab-df0d-436b-9845-6a2f79ad6f99 /boot                   xfs     defaults        0 0
UUID=1ae437de-485a-4f2e-a1b1-4e3327ba6c8a /var                    xfs     defaults        0 0
UUID=7efc21b5-5de1-47c1-8f92-a5b6a0f7f6a0 swap                    swap    defaults        0 0
[[email protected] ~]#

            这里需要说明一下,前面已经说了,无论模式空间中的内容是否被匹配都会默认输出到标准输出上的,也就是第10行被匹配到了,默认就会输出到标准输出,而p是将匹配到的模式空间中的行打印到标准输出,那么第10行就会打印两次。而d不一样,他删除的就是模式空间里的内容,所有模式空间中已经没有被匹配到的行了,所以无法输出。

            因为p的这种特性,所以一般p会和选项-n一起使用,-n是不输出模式空间里的任何默认输出到标准输出的行,而p刚好打印出模式空间中匹配到的行并不是默认输出的行。

[[email protected] ~]# sed -n ‘10p‘ /etc/fstab
UUID=d8644fab-df0d-436b-9845-6a2f79ad6f99 /boot                   xfs     defaults        0 0
[[email protected] ~]#

            看见没,所以一定要注意默认输出和主动打印

                                   a:地址定界中匹配到的行下添加一行或者多行命令 

[[email protected] ~]# sed  ‘10a \a new line‘ /etc/fstab
UUID=d8644fab-df0d-436b-9845-6a2f79ad6f99 /boot                   xfs     defaults        0 0
a new line
UUID=1ae437de-485a-4f2e-a1b1-4e3327ba6c8a /var                    xfs     defaults        0 0
 这里我省略了上下的内容

          这里是添加一行,添加多行的时候只需要使用换行符 

[[email protected] ~]# sed  ‘10a \a new line \n another line‘ /etc/fstab
UUID=d8644fab-df0d-436b-9845-6a2f79ad6f99 /boot                   xfs     defaults        0 0
a new line 
 another lineU 
UID=1ae437de-485a-4f2e-a1b1-4e3327ba6c8a /var                    xfs     defaults        0 0

                                i:与a相反,在地址定界匹配到的行上面添加一行或者多行   

                                c:修改匹配到的地址定界的行

[[email protected] ~]# sed ‘10c \new line‘ /etc/fstab
UUID=2816cce5-45cb-4632-b4ef-d5360260af6c /                       xfs     defaults        0 0
new line
UUID=1ae437de-485a-4f2e-a1b1-4e3327ba6c8a /var                    xfs     defaults        0 0
[[email protected] ~]# sed ‘10c \new line\nanother new line‘ /etc/fstab
UUID=2816cce5-45cb-4632-b4ef-d5360260af6c /                       xfs     defaults        0 0
new line
another new line
UUID=1ae437de-485a-4f2e-a1b1-4e3327ba6c8a /var                    xfs     defaults        0 0
当然也可以在修改的行后面添加新的行

                            w 路径:将模式空间中匹配到的行输出到文件中,但是显示器上还是会显示所有内容,除非用-n选项

[[email protected] ~]# sed -n ‘10w /tmp/atest‘ /etc/fstab
[[email protected] ~]# cat /tmp/atest 
UUID=d8644fab-df0d-436b-9845-6a2f79ad6f99 /boot                   xfs     defaults        0 0

[[email protected] ~]# sed ‘10w /tmp/atest‘ /etc/fstab

[[email protected] ~]# sed ‘10w /tmp/atest2‘ /etc/fstab
#
# /etc/fstab
# Created by anaconda on Sat Mar 12 16:15:59 2016
#
# Accessible filesystems, by reference, are maintained under ‘/dev/disk‘
# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
#
UUID=2816cce5-45cb-4632-b4ef-d5360260af6c /                       xfs     defaults        0 0
UUID=d8644fab-df0d-436b-9845-6a2f79ad6f99 /boot                   xfs     defaults        0 0
UUID=1ae437de-485a-4f2e-a1b1-4e3327ba6c8a /var                    xfs     defaults        0 0
UUID=7efc21b5-5de1-47c1-8f92-a5b6a0f7f6a0 swap                    swap    defaults        0 0
[[email protected] ~]#  
[[email protected] ~]# cat /tmp/atest2
UUID=d8644fab-df0d-436b-9845-6a2f79ad6f99 /boot                   xfs     defaults        0 0
[[email protected] ~]#

                              r 文件路径:读取指定文件到地址定界匹配到的行的下面

[[email protected] ~]# echo "this is a test">/tmp/atest3
[[email protected] ~]# sed ‘1~2r /tmp/atest3‘ /etc/fstab
this is a test
#
# /etc/fstab
this is a test
# Created by anaconda on Sat Mar 12 16:15:59 2016
#
this is a test
# Accessible filesystems, by reference, are maintained under ‘/dev/disk‘
# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
this is a test
#
UUID=2816cce5-45cb-4632-b4ef-d5360260af6c /                       xfs     defaults        0 0
this is a test
UUID=d8644fab-df0d-436b-9845-6a2f79ad6f99 /boot                   xfs     defaults        0 0
UUID=1ae437de-485a-4f2e-a1b1-4e3327ba6c8a /var                    xfs     defaults        0 0
this is a test
UUID=7efc21b5-5de1-47c1-8f92-a5b6a0f7f6a0 swap                    swap    defaults        0 0
[[email protected] ~]#

                            =:在模式空间中匹配到的行的上面添加匹配到的行的行号

UUID=2816cce5-45cb-4632-b4ef-d5360260af6c /                       xfs     defaults        0 0
10
UUID=d8644fab-df0d-436b-9845-6a2f79ad6f99 /boot                   xfs     defaults        0 0
UUID=1ae437de-485a-4f2e-a1b1-4e3327ba6c8a /var                    xfs     defaults        0 0

                 !执行动作:对模式空间中匹配到的行不执行此操作。没匹配的行执行此承操作

[[email protected] ~]# sed ‘10!=‘ /etc/fstab
1
2
#
3
# /etc/fstab
4
# Created by anaconda on Sat Mar 12 16:15:59 2016
5
#
6
# Accessible filesystems, by reference, are maintained under ‘/dev/disk‘
7
# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
8
#
9
UUID=2816cce5-45cb-4632-b4ef-d5360260af6c /                       xfs     defaults        0 0
UUID=d8644fab-df0d-436b-9845-6a2f79ad6f99 /boot                   xfs     defaults        0 0
11
UUID=1ae437de-485a-4f2e-a1b1-4e3327ba6c8a /var                    xfs     defaults        0 0
12
UUID=7efc21b5-5de1-47c1-8f92-a5b6a0f7f6a0 swap                    swap    defaults        0 0
[[email protected] ~]#

                   s:查找模式空间中匹配到的行的指定内容并替换为其他指定内容

                        s///或者[email protected]@@或者s###默认只替换匹配到的行的第一个匹配到的内容

                        -g:全局替换

                        -p:显示替换成功的行

                        -w 文件路径:将替换成功的行写入指定文件中

[[email protected] ~]# sed ‘10s/^UUID/it work/‘ /etc/fstab
UUID=2816cce5-45cb-4632-b4ef-d5360260af6c /                       xfs     defaults        0 0
it work=d8644fab-df0d-436b-9845-6a2f79ad6f99 /boot                   xfs     defaults        0 0
UUID=1ae437de-485a-4f2e-a1b1-4e3327ba6c8a /var                    xfs     defaults        0 0

    需要注意一下,这个替换不是只替换//中的内容,除非指定整行 

[[email protected] ~]# sed ‘10s/^UUID.*/it work/‘ /etc/fstab 
UUID=2816cce5-45cb-4632-b4ef-d5360260af6c /                       xfs     defaults        0 0
it work
UUID=1ae437de-485a-4f2e-a1b1-4e3327ba6c8a /var                    xfs     defaults        0 0

 再来看看p,和前面的一样,因为默认会把模式空间的内容输出到标准输出,所以p就会把替换成功的行打印出来

[[email protected] ~]# sed ‘10s/UUID/it work/p‘ /etc/fstab 
UUID=2816cce5-45cb-4632-b4ef-d5360260af6c /                       xfs     defaults        0 0
it work=d8644fab-df0d-436b-9845-6a2f79ad6f99 /boot                   xfs     defaults        0 0
it work=d8644fab-df0d-436b-9845-6a2f79ad6f99 /boot                   xfs     defaults        0 0

 再来看看w也是一样,把替换成功的行输出一份到指定文件 

[[email protected] ~]# sed ‘10s/UUID/it work/w /tmp/atest4‘ /etc/fstab
UUID=2816cce5-45cb-4632-b4ef-d5360260af6c /                       xfs     defaults        0 0
it work=d8644fab-df0d-436b-9845-6a2f79ad6f99 /boot                   xfs     defaults        0 0
UUID=1ae437de-485a-4f2e-a1b1-4e3327ba6c8a /var                    xfs     defaults        0 0
UUID=7efc21b5-5de1-47c1-8f92-a5b6a0f7f6a0 swap                    swap    defaults        0 0 
[[email protected] ~]# cat /tmp/atest4
it work=d8644fab-df0d-436b-9845-6a2f79ad6f99 /boot                   xfs     defaults        0 0

 

                    

        

                

            

以上是关于文本处理三剑客之sed基础用法的主要内容,如果未能解决你的问题,请参考以下文章

文本处理三剑客之SED

文本三剑客之sed用法详解

Linux文本处理三剑客之---sed

文本处理三剑客之-sed高级用法

自动化运维必须要学的Shell文本处理三剑客之——sed用法(超多案例详细介绍)

linux文本三剑客之sed命令详解