实例详解linux文本三剑客--sed

作者: 闲睡猫 | 来源:发表于2017-09-24 22:16 被阅读83次
    sed

    简介

    sed是一种流编辑器,以行为单位进行文本处理,可以将数据行进行替换、删除、新增、选取等操作。

    sed [options] 'command' file(s)

    基本命令

    匹配内容

    $ sed 'p' /etc/passwd # 每一行输出两次
    $ sed -n 'p' /etc/passwd # 每行只出现一次
    
    $ sed -n '/root/p' /etc/passwd
    root:x:0:0:root:/root:/bin/zsh
    # 等同于
    $ grep 'root' /etc/passwd     
    root:x:0:0:root:/root:/bin/zsh
    

    行定位

    • 定位一行
    $ sed -n '10p' /etc/passwd # 打印第10行
    news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
    
    $ nl /etc/passwd | sed -n '10p'
        10  news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
    
    • 定位多行
    $ nl /etc/passwd | sed -n '10,12p' # 指定行数
        10  news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
        11  uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
        12  proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
    
    $ nl /etc/passwd | sed -n '/uuidd/,/sshd/p' # 指定内容 匹配从uuidd到sshd的行
        27  uuidd:x:108:112::/run/uuidd:/bin/false
        28  dnsmasq:x:109:65534:dnsmasq,,,:/var/lib/misc:/bin/false
        29  sshd:x:110:65534::/var/run/sshd:/usr/sbin/nologin
    
    • 反向匹配
    $ nl /etc/passwd | sed -n '10!p' # 匹配第10行之外的内容
    $ nl /etc/passwd | sed -n '10,20!p' # 匹配除第10至20行之外的内容
    
    • 间隔行
    $ nl passwd | sed -n '1~2p' # 从第1行开始,每隔2行打印
         1  root:x:0:0:root:/root:/bin/zsh
         3  bin:x:2:2:bin:/bin:/usr/sbin/nologin
         5  sync:x:4:65534:sync:/bin:/bin/sync
         7  man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
         ...
    

    新增行

    $ nl /etc/passwd | sed '2a======='  # 在第2行下新增一行,内容为=======
         1  root:x:0:0:root:/root:/bin/zsh
         2  daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
    =======
         3  bin:x:2:2:bin:/bin:/usr/sbin/nologin
         ...
    
    $ nl /etc/passwd | sed '1,3a=======' # 在第1至3行,每行后面都新增内容
         1  root:x:0:0:root:/root:/bin/zsh
    =======
         2  daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
    =======
         3  bin:x:2:2:bin:/bin:/usr/sbin/nologin
    =======
         4  sys:x:3:3:sys:/dev:/usr/sbin/nologin
         ...
    

    插入行

    $ nl /etc/passwd | sed '1,3i======='
    =======
         1  root:x:0:0:root:/root:/bin/zsh
    =======
         2  daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
    =======
         3  bin:x:2:2:bin:/bin:/usr/sbin/nologin
    

    替代行

    $ nl /etc/passwd | sed '1,3c======='
    =======
         4  sys:x:3:3:sys:/dev:/usr/sbin/nologin
    

    替换是整体替换,而不是每一行替换

    删除行

    $ nl /etc/passwd | sed '1,3d'       
         4  sys:x:3:3:sys:/dev:/usr/sbin/nologin
         5  sync:x:4:65534:sync:/bin:/bin/sync
    

    删除空行

    $ sed '/^$/d' /etc/passwd
    

    在文件末尾追加内容

    $ sed '$a test1\ntest2' /etc/passwd
    ...
    mysql:x:112:116:MySQL Server,,,:/nonexistent:/bin/false
    test1
    test2
    

    替换

    $ sed 's/false/true/' /etc/passwd # 仅替换每一行的第一个
    $ sed 's/false/true/g' /etc/passwd # 全局替换每行出现的文本
    

    筛选数据

    $ ifconfig | sed -n '/inet /p' | sed 's/inet.*r://' | sed 's/B.*//' | 
    sed 's/M.*//'
              127.0.0.1  
              192.168.1.6  
    

    获取不连续的行

    $ nl passwd | sed -n -e '2,3p' -e '10,12p'
         2  daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
         3  bin:x:2:2:bin:/bin:/usr/sbin/nologin
        10  news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
        11  uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
        12  proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
    

    忽略大小写

    sed 's/linux/unix/gi' /etc/passwd
    

    写入空行

    sed G /etc/passwd # 在每行之后新增一行
    sed 'G;G' /etc/passwd # 在每行之后新增两行
    

    修改原文件

    • 直接修改原文件
    sed -i 's/linux/unix/' /etc/passwd
    
    • 拷贝原文件副本再进行修改
    $ sed -i'.orig' 's/linux/unix/gi' /etc/passwd
    $ ls /etc/passwd.*  
    passwd  passwd.orig
    

    小括号反向引用

    $ sed 's/\(unix\)/learn \1/g' /etc/passwd
    

    仅当符合某条件时才进行内容替换

    sed '/learn/s/unix/linux/g' /etc/passwd 
    

    当行中同时存在learn及unix时,才将unix替换为linux

    批量替换

    sed 's/mysql/mysql_user/gi;s/linux/unix/gi' /etc/passwd
    

    高级命令

    执行多个sed命令

    -{}: 用;分开多个sed命令

    nl /etc/passwd | sed '{20,30d;s/false/true/}' # 删除第20至30行,将false替换成true
    

    读取一个输入 行

    $ nl passwd | sed -n '{n;p}'  # 间隔了一行取出 偶数行
    $ nl passwd | sed -n '{p;n}' # 奇数行输出
    
    # 另一种实现方式
    $ nl passwd | sed '1~2p'
    $ nl passwd | sed '2~2p'
    
    $ nl passwd | sed -n '{n;n;p}'
         3  daemon:x:2:2:daemon:/sbin:/sbin/nologin
         6  sync:x:5:0:sync:/sbin:/bin/sync
         9  mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
    
    $ nl passwd | sed -n '{n;p;n}'
         2  bin:x:1:1:bin:/bin:/sbin/nologin
         5  lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
         8  halt:x:7:0:halt:/sbin:/sbin/halt
    

    替换固定字符串

    $ sed 's/^[a-z_-]\+/& /' /etc/passwd # 用户名后加上空格
    $ sed 's/^[a-z_-]\+/\U&/' /etc/passwd # 将用户名替换成大写
    

    数据筛选

    $ sed 's/\(^[a-z0-9_-]\+\):x:\([0-9]\+\):\([0-9]\+\):.*$/user:\1 uid:\
    2 gid:\3/' /etc/passwd
    user:root uid:0 gid:0
    user:daemon uid:1 gid:1
    user:bin uid:2 gid:2
    ...
    

    复制指定文件插入到匹配行

    $ echo -e '2412424124\n3432534\n5353523523' > 123.txt
    $ echo -e 'dfgetetetete\njpkpwefwe\nlidwoew' > abc.txt
    $ sed '1r 123.txt' abc.txt  # 将123.txt插入到abc.txt的第1行后面
    dfgetetetete
    2412424124
    3432534
    5353523523
    jpkpwefwe
    lidwoew
    

    读文件并不改变两个文件的内容,只是输出,需要用重定向将结果保存

    提前退出

    $ nl /etc/passwd | sed '3q'  # 只取出前3行
         1  root:x:0:0:root:/root:/bin/zsh
         2  daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
         3  bin:x:2:2:bin:/bin:/usr/sbin/nologin
    
    $ nl /etc/passwd | sed '/nologin/q' # 找到第一个nologin就退出
         1  root:x:0:0:root:/root:/bin/zsh
         2  daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
    

    相关文章

      网友评论

        本文标题:实例详解linux文本三剑客--sed

        本文链接:https://www.haomeiwen.com/subject/camlextx.html