• 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏吧

文本三剑客之sed的用法

开发技术 开发技术 3周前 (09-06) 20次浏览

第1章            Sed命令

1.1  sed 命令执行过程

文本三剑客之sed的用法

 

 1.2  sed介绍

sed是一种流编辑器,它一次处理一行内容。处理时,把当前处理的行存储在临时缓冲区中,称为“模式空间”(pattern space),接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。然后读入下行,执行下一个循环。如果没有使诸如‘D’的特殊命令,那会在两个循环之间清空模式空间,但不会清空保留空间。这样不断重复,直到文件末尾。文件内容并没有改变,除非你使用重定向存储输出或者-i进行修改。

1.3  sed功能

功能:主要用来自动编辑一个或多个文件,简化对文件的反复操作,编写转换程序等
参考:http://www.gnu.org/software/sed/manual/sed.html

1.4 sed用法

sed[option]... 'script' inputfile...
常用选项:
-n:不输出模式空间内容到屏幕,即不自动打印
-e:多点编辑
-f: /PATH/SCRIPT_FILE从指定文件中读取编辑脚本
-r:支持使用扩展正则表达式
-i:直接将处理的结果写入文件
-i.bak:备份文件并原处编辑

script:’地址命令’

地址定界:
(1) 不给地址:对全文进行处理

(2) 单地址:

    #: 指定的行,$:最后一行
    /pattern/:被此处模式所能够匹配到的每一行

(3) 地址范围:

    #,#
    #,+#
    /pat1/,/pat2/
    #,/pat1/

(4) ~:步进

    1~2 奇数行
    2~2 偶数行

编辑命令command

d: 删除模式空间匹配的行,并立即启用下一轮循环
p: 打印当前模式空间内容,追加到默认输出之后
a: []text在指定行后面追加文本,支持使用n实现多行追加
i: []text在行前面插入文本
c: []text替换行为单行或多行文本
w: /path/file保存模式匹配的行至指定文件
r: /path/file读取指定文件的文本至模式空间中匹配到的行后
=: 为模式空间中的行打印行号
!: 模式空间中匹配行取反处理

查找替换

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

替换标记:

     g:行内全局替换
     p:显示替换成功的行
     w:/PATH/FILE将替换成功的行保存至文件中
        sed命令的指示信息
        p   print  输出信息
        i   insert 输入信息,在指定信息前面插入新的信息
        a   append 附加信息,在指定信息后面附加新的信息                    
        d   delete 删除指定信息
        s   substitute 替换信息 s###g(全局替换)
        c   替换修改指定的一整行信息   
 

   使用sed查找文件的行

              1 行号 3p                                                 # p  print 打印输出

              2 连续的行号 3,5p                                   # 输出第3行到第5行 ,表示序列

              3 过滤找出包含xxx的行  /oldboy/p         # 按照匹配字符串的方式模式查找

              4 过滤范围 //,//p

         示例1:输出打印文件的第三行

[root@oldboyedu-lnb ~]# sed -n '3p' oldboy.txt
test

        示例2:输出文件的3-6行  包含空行

                 格式: sed ‘n,np’ file
                          sed ‘3,6p’ file
 [root@oldboyedu-lnb ~]# sed -n '3,6p' oldboy.txt
 test
 I like badminton ball ,billiard ball and chinese chess!
 my blog is http: blog.51cto.com

 示例3: 输出文件的最后一行 $

[root@oldboyedu-lnb ~]# sed -n '$p' oldboy.txt
11111111818181818
[root@oldboyedu-lnb ~]# sed -n '15,$p' oldboy.txt
hehe
$m
11111111818181818

  示例4:取出网卡的第二行

[root@oldboyedu-lnb ~]# ifconfig eth0|sed -n '2p'
inet 10.0.0.200  netmask 255.255.255.0  broadcast 10.0.0.255

  示例5:根据行号信息,输出多行内容(不连续)

[root@oldboyedu ~]# sed -n '1p;3p' person.txt
101,oldboy,CEO
103,Alex,COO

   根据内容信息,输出多行内容(连续)

      示例6: #将有oldboy到alex行的信息都输出出来 

 [root@oldboyedu ~]# sed -n '/oldboy/,/Alex/p' person.txt
 101,oldboy,CEO
 102,zhaoyao,CTO
 103,Alex,COO

      示例7:#将有oldboy和alex行的信息都输出出来   

  [root@oldboyedu ~]# sed -n '/oldboy/p;/Alex/p' person.txt
  101,oldboy,CEO
  103,Alex,COO
  106,oldboy,CIO 

      示例8:在文件第一行添加信息

        [root@oldboyedu ~]# sed  '1i100,oldgirl,UFO' person.txt
        100,oldgirl,UFO
        101,oldboy,CEO
        102,zhaoyao,CTO
        103,Alex,COO
        104,yy,CFO
        105,feixue,CIO
        106,oldboy,CIO

       示例9:在文件最后一行添加信息 

        [root@oldboyedu ~]# sed  '$a108,oldgirl,UFO' person.txt

        100,oldgirl,UFO

        101,oldboy,CEO

        102,zhaoyao,CTO

        103,Alex,COO

        104,yy,CFO

        105,feixue,CIO

        106,oldboy,CIO

        108,oldgirl,UFO

 测试:

       01. 在第三行后面添加oldboy.txt信息

sed '3aoldboy.txt' person.txt

       02. 在第二行前面添加oldboy.txt信息

 sed '2ioldboy.txt' person.txt

       03. 在有oldboy行的前面添加oldgirl 后面添加olddog信息   

 sed -e '/oldboy/ioldgirl' -e  '/oldboy/aolddog' person.txt

     创建测试环境: 

    -rw-r--r--. 1 root root      0 Oct 10 02:10 oldboy01.txt

    -rw-r--r--. 1 root root      0 Oct 10 02:10 oldboy02.txt

    -rw-r--r--. 1 root root      0 Oct 10 02:10 oldboy03.txt

    -rw-r--r--. 1 root root      0 Oct 10 02:10 oldboy04.txt

    -rw-r--r--. 1 root root      0 Oct 10 02:10 oldboy05.txt

    -rw-r--r--. 1 root root      0 Oct 10 02:10 oldboy06.txt

    -rw-r--r--. 1 root root      0 Oct 10 02:10 oldboy07.txt

    -rw-r--r--. 1 root root      0 Oct 10 02:10 oldboy08.txt

    -rw-r--r--. 1 root root      0 Oct 10 02:10 oldboy09.txt

    -rw-r--r--. 1 root root      0 Oct 10 02:10 oldboy10.txt

       批量修改文件的扩展名称 将oldboyxx.txt扩展名修改为oldboyxx.jpg

    [root@oldboyedu oldboy]# ls oldboy*.txt|sed -r 's#(.*)txt#mv &(表示oldboy*.txt) 1(表  示oldboy*)jpg#g'

    mv oldboy01.txt oldboy01.jpg

    mv oldboy02.txt oldboy02.jpg

    mv oldboy03.txt oldboy03.jpg

    mv oldboy04.txt oldboy04.jpg

    mv oldboy05.txt oldboy05.jpg

    mv oldboy06.txt oldboy06.jpg

    mv oldboy07.txt oldboy07.jpg

    mv oldboy08.txt oldboy08.jpg

    mv oldboy09.txt oldboy09.jpg

    mv oldboy10.txt oldboy10.jpg

    mv oldboy.txt oldboy.jpg

1.5    sed 的模糊匹配

语法格式:

       grep ‘过滤的内容’  file

       sed ‘/过滤的内容/动作’ file

       sed的增删改查之查看过滤文件内容

       示例1:过滤包含http的行

[root@oldboyedu-lnb ~]# sed -n '/http/p' oldboy.txt
my blog is http: blog.51cto.com
our site is http:www.lizhenya.com

       示例2: 过滤包含http或lizhenya的行使用或者|

              语法格式:

                                    格式: sed ‘n,np’ file
                                      sed ‘3,6p’ file
       [root@oldboyedu-lnb ~]# sed -nr '/http|lizhenya/p' oldboy.txt

        I am lizhenya teacher!

        my blog is http: blog.51cto.com

        our site is http:www.lizhenya.com

        lizhenyalizhenyalizhenyaaaaaaaaa

       示例3: 过滤字符串的区间 使用行可以过滤区间 sed ‘1,3p’ file

                  语法格式:

                  sed ‘/字符串/,/字符串/p’ file 

 [root@oldboyedu-lnb ~]# sed -n '/test/,/not/p' oldboy.txt
 test
 I like badminton ball ,billiard ball and chinese chess!
 my blog is http: blog.51cto.com
 our site is http:www.lizhenya.com
 my qq num is 593528156
 aaaa,
 not 572891888887.

      工作中匹配日志时间区间     

 [root@oldboyedu-lnb ~]# sed -n '/Aug  6 08:09:26/,/Aug  7 08:09:23/p' /var/log/messages 

区间模糊匹配的注意事项:

              a)模糊匹配的结束字符 如果文件的后面有多个相同的字符 以第一个为结界

              b)模糊匹配的开始字符 如果文件匹配字符结束 后还有开始的字符 没有结束的字符 则匹配内容到文件的末尾

1.6    sed 增加内容模式

sed 增加内容  临时增加内容 只输出到屏幕上 不会更改源文件

        vi vim echo cat

           -a    append  追加      # 在当前行的下一行追加内容  当前3 第4行插入的新的内容

           -i     insert  插入      # 在当前行插入内容        当前3 插入3行前的内容

           -c   change  替换       # 把当前行的内容进行替换

         语法格式:

                     sed ‘3a 插入的内容’ file

              示例1: 在当前行插入 

[root@oldboyedu-lnb ~]# sed '3i alex' oldboy.txt.bak
I am lizhenya teacher!
I teach linux.
hehe
test

              示例2: 在当前行追加新的内容     

[root@oldboyedu-lnb ~]# sed '3a prot=9777' oldboy.txt.bak
I am lizhenya teacher!
I teach linux.
test
prot=9777
      
   [root@oldboyedu-lnb ~]# sed '3,5a alex' oldboy.txt.bak
   I am lizhenya teacher!
   I teach linux.
   test
   alex
   alex
   I like badminton ball ,billiard ball and chinese chess!
   alex

              示例3: 替换第3行的内容为oldboyedu.com            替换整行        

[root@oldboyedu-lnb ~]# sed '3c oldboyedu.com' oldboy.txt.bak
I am lizhenya teacher!
I teach linux.
oldboyedu.com

 案例: 修改selinux的配置文件selinux=disabled

            语法格式: sed -n ‘/模式/动作’ file

                      sed -n ‘/被替换的内容/c 替换的内容’ file    

[root@oldboyedu-lnb ~]# sed -n '/^SELINUX=/c SELINUX=enforcing' /etc/selinux/config
SELINUX=enforcing
[root@oldboyedu-lnb ~]# sed -in '/^SELINUX=/c SELINUX=enforcing' /etc/selinux/config
[root@oldboyedu-lnb ~]# sed -n '/^SELINUX=/c SELINUX=disabled' /etc/selinux/config
SELINUX=disabled

         方法2 按照行替换     

[root@oldboyedu-lnb ~]# sed -n '8c SELINUX=disabled' /etc/selinux/config
SELINUX=disabled
[root@oldboyedu-lnb ~]# sed -in '8c SELINUX=disabled' /etc/selinux/config
[root@oldboyedu-lnb ~]# sed 'a oldboyedu.com' oldboy.txt.bak  了解
I am lizhenya teacher!
oldboyedu.com
I teach linux.
oldboyedu.com
test
oldboyedu.com

1.7    sed的删除

         语法结构:

         sed ‘/模式/动作’ file           # 不加参数只是临时删除 不影响源文件

         sed ‘3d’ file

         sed ‘/oldboy/d’ file

         示例1: 删除第三行              

[root@oldboyedu-lnb ~]# sed '3d' oldboy.txt.bak
I am lizhenya teacher!
I teach linux.

          示例2: 删除1-3      

[root@oldboyedu-lnb ~]# sed '1,3d' oldboy.txt.bak
[root@oldboyedu-lnb ~]# sed '1,$d' oldboy.txt.bak 

           示例3: 字符匹配删除 删除包含linux的行

[root@oldboyedu-lnb ~]# sed '/linux/d' oldboy.txt.bak

           示例4: 删除匹配的区间

[root@oldboyedu-lnb ~]# sed '/test/,/our/d' oldboy.txt.bak
I am lizhenya teacher!
I teach linux.
my qq num is 593528156

1.8    sed 的内容替换             

语法格式:

                sed ‘s#被替换内容#替换成什么#g’ file

              ‘s@@@g’

              ‘s///g’

              s  sub

              g  global 全局替换

             示例1: 替换文件中的每行第一个test为oldboy  了解

                                     s###  替换文件中每行的第一个test

                                     sed ‘s###’  类似于 vim中的 %s###           

[root@oldboyedu-lnb ~]# sed 's#test#oldboyedu.com#' oldboy.txt.bak
I am lizhenya teacher!
I teach linux.
oldboyedu.com test test test

            示例2: 替换文件中所有的test为oldboyedu.com

                       sed ‘s###g’ file 
[root@oldboyedu-lnb ~]# sed 's#test#oldboyedu.com#g' oldboy.txt.bak
                      永久替换              
 [root@oldboyedu-lnb ~]# sed -i 's#test#oldboyedu.com#g' oldboy.txt.bak

           示例3:把文件第2,5行中的小写字母删除  有n 必须有p 才能输出结果 

[root@oldboyedu-lnb ~]# sed -n '3,5p' oldboy.txt.bak|sed 's#[a-z]##g'
. . . .
I    .,    !
[root@oldboyedu-lnb ~]# sed  -n '3,5s#[a-z]##gp' oldboy.txt.bak
. . . .
I    .,    !

1.9    sed替换的注意事项:

         s### s///  看文件中是否存在### ///     
[root@oldboyedu-lnb ~]# head -1 passwd |sed 's//root/test/g'
sed: -e expression #1, char 9: unknown option to `s'
[root@oldboyedu-lnb ~]# head -1 passwd |sed 's//root/test/g'
root:x:0:0:root:test:/bin/bash
[root@oldboyedu-lnb ~]#
[root@oldboyedu-lnb ~]# head -1 passwd |sed 's#/root#test#g'
root:x:0:0:root:test:/bin/bash
[root@oldboyedu-lnb ~]# head -1 passwd |sed 's##hehe#test#g'
root:x:test0:0:root:/root:/bin/bash

1.10    sed 的后向引用

                     语法格式: 先保护  后引用

                             ()      引用()中的内容 支持正则
                      1      表示第一个()的内容
                      2      表示第二个()的内容

              调用()内容的前面和后面可以加任意的内容

[root@oldboyedu-lnb ~]# echo 123456|sed -r 's#(.*)#1#g'
 123456
[root@oldboyedu-lnb ~]# echo 123456|sed -r 's#(.*)#<<1>>#g'
<<123456>>
[root@oldboyedu-lnb ~]# echo 123456|sed -r 's#(.*)#hehe1hehe#g'
hehe123456hehe
[root@oldboyedu-lnb ~]# echo 123456|sed -r 's#(.*)#111111111#g'
11111234561111
[root@oldboyedu-lnb ~]# echo 123456|sed -r 's#([0-9]{3})#1#g'
123456
[root@oldboyedu-lnb ~]# echo 123456|sed -r 's#([0-9]{3})#<1>#g'
<123><456>
[root@oldboyedu-lnb ~]# echo 123456|grep '[0-9]{3}' -o
[root@oldboyedu-lnb ~]# echo 123456|egrep '[0-9]{3}' -o
123
456

   案例: sed 后向引用获取IP地址

[root@oldboyedu-lnb ~]# ifconfig eth0|sed -n '2p'|sed -r 's#^.*inet (.*)  netmask.*$#1#g'
10.0.0.200
[root@oldboyedu-lnb ~]# ifconfig eth0|sed -n '2p'|sed -r 's#(^.*inet )(.*) netmask.*$#1#g'
inet
[root@oldboyedu-lnb ~]# ifconfig eth0|sed –n '2p'|sed-r's#(^.*inet )(.*)(  netmask.*$)#3#g'
netmask 255.255.255.0  broadcast 10.0.0.255
[root@oldboyedu-lnb ~]# ifconfig eth0|sed -n '2p'|sed -r 's#(^.*inet )(.*)(  netmask.*$)#2#g'
10.0.0.200    

使用ip add 取出IP地址和子网掩码

[root@oldboyedu-lnb ~]# ip add|grep -n .
[root@oldboyedu-lnb ~]# ip add|sed -nr '9s#^.*net (.*)/24.*$#1#gp'
10.0.0.200
[root@oldboyedu-lnb~]# ip add |sed -n '9p' |sed -r 's#^.*brd(.*)scop.*$#1#g'
10.0.0.255
[root@oldboyedu-lnb~]# ip add |sed -nr '9s#^.*brd(.*)scop.*$#1#gp'
10.0.0.255

   1.11   练习题

    1.11.1   将/etc/passwd文件的第3行到第7行另存为/tmp/passwd

[root@oldboyedu-lnb~]# cat /etc/passwd |sed -n '3,7p' > /tmp/passwd
[root@oldboyedu-lnb~]# cat /tmp/passwd
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown

   1.11.2   在/tmp/passwd文件中的第3行前插入下面两行文字

                  good good study, day day up.

                  Come here, change yourself.

[root@oldboyedu-lnb~]# sed  '3ingood good study, day day up.nCome here,change yourself.' /tmp/passwd
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
ngood good study, day day up.
Come here,change yourself.
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown

  1.11.3    将/tmp/passwd文件中的所有/sbin/nologin替换为/bin/bash

[root@oldboyedu-lnb~]# sed -n 's#/sbin/nologin#/bin/bash#gp' /tmp/passwd
daemon:x:2:2:daemon:/sbin:/bin/bash
adm:x:3:4:adm:/var/adm:/bin/bash
lp:x:4:7:lp:/var/spool/lpd:/bin/bash

  1.11.4   删除/tmp/passwd文件中包含bin单词的行

[root@oldboyedu-lnb~]# sed '/<bin>/d' /tmp/passwd1
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown

1.12    小结sed

              增删改查替换

              查看:

                

                      -n  取消默认输出

                      -r  支持扩展正则

                      -i  更改源文件

                      sed -n '3p' file

                                    1,3p

                                    3,$p

                      sed -n '/root/p' file

                      sed -n '/root/,/alex/p' file

        增加替换:

            

                     -i 

                     -a

                     -c

        sed '3i 新的内容' file

       sed '3a 追加内容' file

       sed '3c 替换整行内容' file 

              组合使用:

sed '3,5c oldboyedu' file
sed '/root/c oldboyedu' file
修改源文件 -i参数
sed的替换:
sed 's#替换谁#替换的内容#g' file
cat file |sed 's###g'
sed '3,5p' file|sed 's###g'
组合使用
sed -n '3,5s###gp' file
sed的后向引用
sed -r 's#()#1#g'

 PS: Linux中大部分的命令   -V 都是查看版本信息

grep的参数

            -n    显示匹配到内容的行号

           -v    取反

           -o    显示匹配过程

           -i    不区分大小写

           -E    支持扩展正则

           -R    递归查询文件内容

           -w    过滤单词

           -c    统计字符串在文件中出现的次数

           -A   显示当前查找到的内容往下n行       了解

           -B    显示当前查找到的内容往上n行       了解

           -C    显示当前查找到的内容上下各n行    了解   

 

[root@oldboyedu-lnb ~]# grep oldboy 1.txt
alexoldboylidao
oldboy
oldboyedu.com
[root@oldboyedu-lnb ~]# grep -w oldboy 1.txt
oldboy
[root@oldboyedu-lnb ~]# grep linux -A3 oldboy.txt.bak
 I teach linux.
oldboyedu.com oldboyedu.com oldboyedu.com oldboyedu.com
I like badminton ball oldboyedu.com,billiard ball and chinese chess!
[root@oldboyedu-lnb ~]# grep like -B3 oldboy.txt.bak
I teach linux.
oldboyedu.com oldboyedu.com oldboyedu.com oldboyedu.com
I like badminton ball oldboyedu.com,billiard ball and chinese chess!
[root@oldboyedu-lnb ~]# grep linux -C1 oldboy.txt.bak
I am lizhenya teacher!
I teach linux.
oldboyedu.com oldboyedu.com oldboyedu.com oldboyedu.com

 


喜欢 (0)