• 正则表达式sed学习(二)


    sed
    sed是一个流编辑器,非交互式的编辑器,它一次处理一行内容.
    处理时,把当前处理的行存储在临时缓冲区中,称为“模式空间”(pattern space)
    接着用 sed 命令处理缓冲区的内容,处理完成后,把缓冲区的内容送往屏幕。
    接着处理下一行,这样不断重复,直到文件末尾。
    文件内容并没有改变,除非你使用重定向存储输出。
    sed 要用来自动编辑一个或多个文件;简化对文件的反复操作;编写装换程序等

    sed 增加 修改 查找 删除 增删改查

    #查
    sed单行查询
    sed多行查询(地址范围)
    sed过滤功能

    #增
    sed单行增加
    sed多行增加
    sed增加案例

    #删
    sed删除功能及案例

    #改
    sed文本替换
    sed变量替换
    sed反向引用
    sed替换案例
    sed执行多条语句
    获取文件行号


    1.sed语法格式

    sed [选项] [sed指令] [输入文件]
    scripts:
        地址定界编辑命令
    常用选项:
        -n 不输出模式空间中的内容至屏幕
        -e 多点编辑
        -r 支持扩展正则表达式
        -i 直接编辑源文件    
    地址定界:
        1)空地址:对全文进行处理
        2)单地址
            #:指定行
            /pattern/:被此模式匹配到每一行
        3)地址范围    
            #.#
            #,+#
            #,/part1/
            /part1/,/part2/
        4)步进:~
            1~2:所有奇数行
            2~2:所有偶数行
    编辑命令:
        p: 显示在模式空间的内容
        d: 删除
        a 	ext:在行后面追加文本text,支持
    实现多行追加
        i 	ext:在行前面插入文本text,支持
    实现多行插入
        c 	ext:把匹配到的行替换为此处指定的文件中
        w /path: 保存模式空间匹配到的行至指定的文件中
        r /path:读取指定文件的内容至当前文件模式匹配到的行
        =:为模式匹配到的行打印行号
        !:条件取反
           地址定界!编辑命令:
        s///:查找替换,其分隔符可自行指定,常用的有s@@@,s###等
           替换标记
               g:全局替换
               w /path:将替换成功的结果保存至指定文件中
               p:显示替换成功的行     

    2.sed命令执行流程

    3.创建测试文件

    cat >person.txt<<EOF
    101,oldboy,CEO
    102,zhangyao,CTO
    103,Alex,COO
    104,yy,CFO
    105,feixue,CIO
    EOF

    4.查询单行文本p 显示某一行

    p  sed指定,打印模式空间内容
    -n sed选项,取消默认输出
    
    [root@xiaoming ~]# sed '1p' person.txt 
    101,oldboy,CEO
    101,oldboy,CEO
    102,zhangyao,CTO
    103,Alex,COO
    104,yy,CFO
    105,feixue,CIO
    
    [root@xiaoming ~]# sed '1p' person.txt -n
    101,oldboy,CEO
    #显示文件最后一行
    [root@xiaoming ~]# sed '$p' person.txt -n
    105,feixue,CIO

    5.查询连续多行文本,显示连续的多行,从哪里来到哪里去'1,4p'

    指定p前面没有地址范围,那么默认匹配所有行

    #数字地址范围--推荐 行号
    #2,4 显示第二行到第四行的内容,包含第二行和第四行
    
    [root@xiaoming ~]# sed '2,4p' person.txt -n
    102,zhangyao,CTO
    103,Alex,COO
    104,yy,CFO
    
    
    ##正则地址范围-模糊,容易找多了
    [root@xiaoming ~]# sed -n '/oldboy/p' person.txt 
    101,oldboy,CEO
    [root@xiaoming ~]# sed -n '/o.*y/p' person.txt 
    101,oldboy,CEO
    [root@xiaoming ~]# sed -n '/o.*y/,/105/p' person.txt 
    101,oldboy,CEO
    102,zhangyao,CTO
    103,Alex,COO
    104,yy,CFO
    105,feixue,CIO
    
    
    ##显示这个文件的第一行到第四行
    [root@xiaoming ~]# sed -n '1,4p' person.txt 
    
    ##从包含101的这一行,显示到包含104的这一行
    [root@xiaoming ~]# sed -n '/101/,/104/p' person.txt 
    101,oldboy,CEO
    102,zhangyao,CTO
    103,Alex,COO
    104,yy,CFO

    sed查询功能对比grep
    1.都是基于行为单位
    2.都支持正则
    3.sed可以做指定查询范围,grep不行


    6.过滤多个字符串

    -r sed选项,支持扩展正则表达式(|())
    
    默认情况,sed只支持基本正则表达式。
    [root@xiaoming ~]# egrep 'oldboy|yy' person.txt 
    101,oldboy,CEO
    104,yy,CFO
    
    [root@xiaoming ~]# sed -rn '/oldboy|yy/p' person.txt 
    101,oldboy,CEO
    104,yy,CFO
    
    sed里面的正则字符左右必须有"/"。/oldboy/
    
    重点:
    sed 查询单行文本
    查询多行文本 使用数字地址范围sed '2,4p' person.txt -n

    7.查询指定多行
    使用分号

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

    8.增加单行文本a,i

    我想向person.txt文件中追加2行
    106,lidao,UFO
    107,bingbing,CEO
    方法一:cat
    cat >>person.txt <<EOF
    106,lidao,UFO
    107,bingbing,CEO
    EOF
    
    方法二:echo
    [root@xiaoming ~]# echo "asda
    > asdas
    > asdas"
    asda
    asdas
    asdas
    
    [root@xiaoming ~]# echo "106,lidao,UFO
    107,bingbing,CEO"
    106,lidao,UFO
    107,bingbing,CEO person.txt
    [root@xiaoming ~]# echo -e "106,lidao,UFO
    107,bingbing,CEO" 
    106,lidao,UFO
    107,bingbing,CEO person.txt
    方法三:sed命令
    #在第2行后面加入一个新行,内容为 oldboy.com
    [root@xiaoming ~]# sed '2a oldboy.com' person.txt 
    101,oldboy,CEO
    102,zhangyao,CTO
    oldboy.com
    103,Alex,COO
    
    [root@xiaoming ~]# sed '2i oldboy.com' person.txt 
    101,oldboy,CEO
    oldboy.com
    102,zhangyao,CTO
    
    a  append 追加
    i  insert 插入
    #在最后一行后面追加2行内容
    [root@xiaoming ~]# sed '$a 106,lidao,UFO
    107,bingbing,CEO' person.txt 
    101,oldboy,CEO
    102,zhangyao,CTO
    103,Alex,COO
    104,yy,CFO
    105,feixue,CIO
    106,lidao,UFO
    107,bingbing,CEO

    9.删除文件内容d

    d sed指令,删除文本内容
    $ 代表文件最后一行
    
    #删除第一行
    [root@xiaoming ~]# sed '1d' person.txt 
    102,zhangyao,CTO
    103,Alex,COO
    104,yy,CFO
    105,feixue,CIO
    106,lidao,UFO
    107,bingbing,CEO
    #显示文件内容但不包含第一行
    方法一:
    [root@xiaoming ~]# grep -v 'oldboy' person.txt
    
    方法二:
    [root@xiaoming ~]# sed '/oldboy/d' person.txt
    
    方法三:
    [root@xiaoming ~]# awk '!/oldboy/' person.txt

    10.修改文件内容c

    禁用SELINUX
    sed -i "s/SELINUX=enforcing/SELINUX=disabled/g" /etc/selinux/config
    sed -i "7c SELINU=disabledX" /etc/selinux/config
    sed -i "/^SELINU=/ SELINU=disabledX" /etc/selinux/config

    11.文本替换

    's/old/new/g'
    's@@@g'
    's###g'
    
    s//etc/hosts//etc/hosts.bak/g
    s#/etc/hosts#/etc/hosts.bak#/g
    
    [root@xiaoming ~]# cat person.txt
    101,oldboy,CEO
    102,zhangyao,CTO
    103,Alex,COO
    104,yy,CFO
    105,feixue,CIO
    
    [root@xiaoming ~]# sed 's#[0-9]#oldboy#g' person.txt
    oldboyoldboyoldboy,oldboy,CEO
    oldboyoldboyoldboy,zhangyao,CTO
    oldboyoldboyoldboy,Alex,COO
    oldboyoldboyoldboy,yy,CFO
    oldboyoldboyoldboy,feixue,CIO
    
    [root@xiaoming ~]# sed 's#[0-9]##g' person.txt
    ,oldboy,CEO
    ,zhangyao,CTO
    ,Alex,COO
    ,yy,CFO
    ,feixue,CIO
    //将第1-3行加注释
    [root@xiaoming ~]# sed -i '1,3s@^@#@g' person.txt
    [root@xiaoming ~]# cat person.txt
    ##oldboy01,oldboy,CEO
    ##oldboy02,zhangyao,CTO
    ##oldboy03,Alex,COO
    
    //将第1-3行注释移除
    [root@xiaoming ~]# sed -i '1,3s@#@@g' person.txt
    [root@xiaoming ~]# cat person.txt
    oldboy01,oldboy,CEO
    oldboy02,zhangyao,CTO
    oldboy03,Alex,COO

    反向引用

    [root@xiaoming ~]# echo '101,abc' | egrep -o '[0-9]+'
    101
    [root@xiaoming ~]# echo '101,abc' | sed -r 's#([0-9]+).*#1#'
    101
    [root@xiaoming ~]# echo '101,abc' | sed -r 's#(....)...#1#'
    101,
    [root@xiaoming ~]# echo '101,abc' | sed -r 's#(101),(abc)#21#'
    abc101

    案例:将/etc/fstab里UUID开头的行另存到/tmp/fstab

    方法一:使用grep
    [root@xiaoming ~]# grep ^UUID /etc/fstab >/tmp/fstab
    方法二:使用sed的编辑命令w
    [root@xiaoming ~]# sed -n '/^UUID/w /tmp/fstab' /etc/fstab 

    案例:

    [root@xiaoming ~]# sed -r 's#[0-9]+#room&#' person.txt
    oldboyroom01,oldboy,CEO
    oldboyroom02,zhangyao,CTO
    oldboyroom03,Alex,COO
    oldboyroom04,yy,CFO
    
    [root@xiaoming ~]# sed -r 's#[0-9]+#&room#' person.txt
    oldboy01room,oldboy,CEO
    oldboy02room,zhangyao,CTO

    案例:在指定行后面读入其他文件内容

    [root@xiaoming ~]# sed '/01/r /etc/hosts' person.txt
    oldboy01,oldboy,CEO
    127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
    ::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
    oldboy02,zhangyao,CTO
    oldboy03,Alex,COO

    案例:匹配打印行号

    [root@xiaoming ~]# sed '/yy/=' person.txt
    oldboy01,oldboy,CEO
    oldboy02,zhangyao,CTO
    oldboy03,Alex,COO
    4
    oldboy04,yy,CFO

    案例:取反

    //打印出/etc/fstab非空非注释行
    解法一:
    [root@xiaoming ~]# egrep -v '^(#|$)' /etc/fstab 
    /dev/mapper/centos-root /                       xfs     defaults        0 0
    UUID=19ad14dc-26ff-4b14-86e7-c4e2182e820a /boot                   xfs     defaults        0 0
    /dev/mapper/centos-swap swap                    swap    defaults        0 0
    解法二:
    [root@xiaoming ~]# sed -r '/^(#|$)/d' /etc/fstab 
    [root@xiaoming ~]# sed -nr '/^(#|$)/!p' /etc/fstab 
    /dev/mapper/centos-root /                       xfs     defaults        0 0
    UUID=19ad14dc-26ff-4b14-86e7-c4e2182e820a /boot                   xfs     defaults        0 0
    /dev/mapper/centos-swap swap                    swap    defaults        0 0
    注意:!的位置

    案例:随机取出10位连续小写字符的字符串

    openssl rand -base64 123 | sed 's#[^a-z]##g'| head -c 10
    ###-i 自动备份功能,先备份,在修改文件内容
    [root@xiaoming ~]# sed -ri.bak 's#[0-9]#oldboy#' person.txt
    [root@xiaoming ~]# ll 
    总用量 24
    -rw-r--r-- 1 root root  137 1月   7 22:14 person.txt
    -rw-r--r-- 1 root root  102 1月   7 21:22 person.txt.bak
    获取centos7网卡IP地址
    [root@xiaoming ~]# ifconfig ens33 | sed -nr 's#.*net (.*) netmask.*#1#p'
    10.0.1.31 
    
    [root@xiaoming ~]# ifconfig | awk 'NR==2{print $2}' 
    10.0.1.31

    练习:

    1.通过正则取出绝对路径/var/log/messages的basename
    提示:
    [root@xiaoming ~]# basename /var/log/messages
    messages
    解法一:
    [root@xiaoming ~]# echo '/var/log/messages' | egrep '[^/]+$' -o
    messages
    解法二:
    [root@xiaoming ~]# echo '/var/log/mes1sages' | sed -r 's#/.*/##'
    mes1sages
    解法三:
    [root@xiaoming ~]# echo '/var/log/mes1sages' | sed -r 's#.*/([^/]+$)#1#' 
    mes1sages
    
    
    2.通过正则取出绝对路劲/var/log/messages的dirname
    提示:
    [root@xiaoming ~]# dirname /var/log/messages
    /var/log
    
    解法一:
    [root@xiaoming ~]# echo '/var/log/mes1sages' | egrep '^/.+/' -o
    /var/log/
    解法二:
    [root@xiaoming ~]# echo '/var/log/mes1sages' | sed -r 's#[^/]+$##'
    /var/log/
    解法三:
    [root@xiaoming ~]# echo '/var/log/mes1sages' | sed -r 's#(.*)/.*#1#' 
    /var/log
  • 相关阅读:
    Windows下Goland的Terminal设置为Git Bash
    BoltDB简单使用教程
    Base64编码转换原理
    [区块链|非对称加密] 对数字证书(CA认证)原理的回顾
    [数据库锁机制] 深入理解乐观锁、悲观锁以及CAS乐观锁的实现机制原理分析
    升级mojave后的小问题解决
    ubuntu安装ssh服务记录
    dubbo+maven多模块项目单元测试
    sass与less
    (转)初识 Lucene
  • 原文地址:https://www.cnblogs.com/xmtxh/p/12164139.html
Copyright © 2020-2023  润新知