zoukankan      html  css  js  c++  java
  • shell编程学习笔记之sed编辑器

     在shell编程中,大多数处理的都是文本文件。对文本文件进行处理除了使用交互式文本编辑器(vi[m],gedit......)也可以使用另外一类:流编辑器。

      流编辑器:使用预定义的编辑规则来对文本进行处理。如sed,gawk

    本文将会记录学习的sed的一些命令,以及一些正则联合使用来对文本进行操作案例.


    第一部分:sed简述

    1.1 sed的使用方法

      sed编辑器是以行为单位来对文本处理的编辑器。它的使用方法有两种:

      sed [选项]  命令  目标文本

      sed [选项]  -f  脚本文件  目标文件

      其中的脚本文件是预先定义好的一些脚本文件,来对目标文件进行处理。

    1.2 sed的工作流程

      sed每次从输入读取一行数据,讲数据与所提供的编辑器命令匹配,根据命令修改数据流中的数据,然后会将新数据输出到标准输出上。如果想要保存修改,需要将修改进行重定向


     第二部分 sed常用命令与示例

      2.1 打印行

        p:打印当前文本文件的指定内容(可指定行或者使用正则表达式匹配指定)

        -n:忽略当前文本内容的自动打印。也就是说默认情况下,sed命令会讲文本处理结果输出到标准输出(终端界面),使用该命令可以关闭自动输出结果到屏幕。

        -n常与p命令联合使用。

      简单应用

    示例:简单应用
    $ sed 'p' passwd | head -n 4  
    root:x:0:0:root:/root:/bin/bash
    root:x:0:0:root:/root:/bin/bash
    daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
    daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
    
    $ sed -n 'p' passwd | head -n 4 
    root:x:0:0:root:/root:/bin/bash
    daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
    bin:x:2:2:bin:/bin:/usr/sbin/nologin
    sys:x:3:3:sys:/dev:/usr/sbin/nologin

        我们可以看到使用p命令打印时,会讲每一行都会输出两次,原因就是sed是对行操作,将一行读取到缓存后,会对这一行按照p命令打印,同时也会默认自动打印。使用-n命令后,文件每行内容只输出一遍。

      打印单行

    示例:打印单行
    
    #指定打印第二行
    $ nl passwd| sed -n  '2p'    
         2    daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
    
    #指定打印含有root字符的行
    $sed -n '/root/p' passwd       
    root:x:0:0:root:/root:/bin/bash
    #注意:通过正则表达式对文本内容匹配时需要按照/****/的形式使用正则表达式

      打印多行 

    示例:打印多行
    
    #打印2-5行
    $ nl passwd | sed -n '2,5p' 
         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
         5    sync:x:4:65534:sync:/bin:/bin/sync
    
    #使用正则打印daemon到sync行的内容
    $ nl passwd | sed -n '/root/,/qi/p'
         1    root:x:0:0:root:/root:/bin/bash
         2    daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
       ......篇幅有限,内容省略......
        42    qi:x:1000:1000:zhuandshao,,,:/home/qi:/bin/bash

       不打印某些行

    示例:不打印某一行
    
    #不打印第1行  使用!进行反选取操作
    $ nl passwd | sed -n '1!p' 
         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
    
    #不打印1-3行 
    $ nl passwd | sed -n '1,3!p'
         4    sys:x:3:3:sys:/dev:/usr/sbin/nologin
         5    sync:x:4:65534:sync:/bin:/bin/sync
         6    games:x:5:60:games:/usr/games:/usr/sbin/nologin

      间隔取行

    示例:间隔取行
    
    #使用first~step 这样的形式来进行间隔几行的操作
    $ nl passwd | sed -n '1~3p' 
         1    root:x:0:0:root:/root:/bin/bash
         4    sys:x:3:3:sys:/dev:/usr/sbin/nologin
         7    man:x:6:12:man:/var/cache/man:/usr/sbin/nologin

      2.2 新增行、插入行 

        a:在每行的行后新增加一行。可使用行号或模式匹配

        i:在指定行前插入一行。可使用行号或模式匹配

      简单应用

    示例:简单应用
    
    #新增一行  
    $ nl passwd|sed '1a        this is a new line behind first line'   #注:使用是为了转义空格以便输出格式对齐
         1    root:x:0:0:root:/root:/bin/bash
            this is a new line behind first line
         2    daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
    
    #插入一行
    $ nl passwd|sed '1i        this is a new line before first line'  
            this is a new line before first line
         1    root:x:0:0:root:/root:/bin/bash
         2    daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin

      范围新增多行与范围插入多行

    示例:范围新增多行与范围插入多行
    
    # :换行 $
    nl passwd|sed '1,2a this is a new line behind two lines  this is second line' | head 1 root:x:0:0:root:/root:/bin/bash this is a new line behind two lines  this is second line 2 daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin this is a new line behind two lines  this is second line 3 bin:x:2:2:bin:/bin:/usr/sbin/nologin 4 sys:x:3:3:sys:/dev:/usr/sbin/nologin $ nl passwd|sed '1,2i this is a new line before two lines  n this is second line' | head this is a new line before two lines  this is second line 1 root:x:0:0:root:/root:/bin/bash this is a new line before two lines  this is second line 2 daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin 3 bin:x:2:2:bin:/bin:/usr/sbin/nologin

      间隔多行插入或者增加

    示例:间隔多行插入或者增加
    
    $ nl passwd|sed '1~2i        this is a new line before two lines 
           this is second line' | head 
            this is a new line before two lines 
           this is second line
         1    root:x:0:0:root:/root:/bin/bash
         2    daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
            this is a new line before two lines 
           this is second line
         3    bin:x:2:2:bin:/bin:/usr/sbin/nologin
         4    sys:x:3:3:sys:/dev:/usr/sbin/nologin
    
    #增加与插入类似,略

      

      2.3 替代行

        c:替代指定行,可使用行号或模式匹配

    示例:简单使用
    
    #替换一行
    $ nl passwd | sed '1c this is a replace line '| head 
    this is a replace line 
         2    daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
         3    bin:x:2:2:bin:/bin:/usr/sbin/nologin
    
    $ nl passwd | sed '/root/c this is a replace line '| head 
    this is a replace line 
         2    daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
         3    bin:x:2:2:bin:/bin:/usr/sbin/nologin
    
    
    #多行整体替换
    $ nl passwd | sed '1,5c this is a replace line '| head 
    this is a replace line 
         6    games:x:5:60:games:/usr/games:/usr/sbin/nologin
         7    man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
    
    $ nl passwd | sed '/root/,/qi/c this is a replace line '| head 
    this is a replace line 
        43    sshd:x:123:65534::/run/sshd:/usr/sbin/nologin
        44    statd:x:125:65534::/var/lib/nfs:/bin/false

      2.4 删除行

        d:删除指定行,可使用行号或模式匹配

      

    示例:简单使用
    
    #删除一行
    $ nl passwd | sed '1d' 
         2    daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
         3    bin:x:2:2:bin:/bin:/usr/sbin/nologin
    
    $ nl passwd | sed '/root/d' 
         2    daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
         3    bin:x:2:2:bin:/bin:/usr/sbin/nologin
    
    
    #删除多行
    $ nl passwd | sed '1,42 d'
        43    sshd:x:123:65534::/run/sshd:/usr/sbin/nologin
        44    statd:x:125:65534::/var/lib/nfs:/bin/false
    
    $ nl passwd | sed '/root/,/qi/d'
        43    sshd:x:123:65534::/run/sshd:/usr/sbin/nologin
        44    statd:x:125:65534::/var/lib/nfs:/bin/false
    
    
    #间隔删除
    $ nl passwd | sed '1~2 d'
         2    daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
         4    sys:x:3:3:sys:/dev:/usr/sbin/nologin
         6    games:x:5:60:games:/usr/games:/usr/sbin/nologin

      2.5 字符转换

        y:将原字符一一转换成目标字符,如y/abc/123/ :将文本中的a-->1 , b-->2 , c--> 3.

    示例:
    $ sed 'y/rs/12/' passwd 
    1oot:x:0:0:1oot:/1oot:/bin/ba2h
    daemon:x:1:1:daemon:/u21/2bin:/u21/2bin/nologin
    bin:x:2:2:bin:/bin:/u21/2bin/nologin
    2y2:x:3:3:2y2:/dev:/u21/2bin/nologin
    2ync:x:4:65534:2ync:/bin:/bin/2ync

      2.6 内容替换

        s:替换匹配的指定的字符,使用方法:s/pattern/replacemet/[flags]

          s命令可用的flags有:

            g:替换所有与pattern匹配的文本,而不是只匹配第一个

            n:n代表数字,指定替换第n个与pattern匹配的文本。默认为第一个。

            w file:如果替换成功就将其写入到file文件中。

            

    示例:
    
    $ sed 's/false/true/' passwd  | grep true 
    systemd-timesync:x:100:102:systemd Time Synchronization,,,:/run/systemd:/bin/true
    
    $ sed 's/:/ % /' passwd        #匹配到第一个:就停止了匹配,如果想要替换所有的,就需要使用全局替换
    root % x:0:0:root:/root:/bin/bash
    daemon % x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
    
    #全局替换 使用g命令
    $ sed 's/:/ % /g' passwd | head 
    root % x % 0 % 0 % root % /root % /bin/bash
    daemon % x % 1 % 1 % daemon % /usr/sbin % /usr/sbin/nologin

    #指定第几个替换
    $ sed 's/:/ % /3' passwd
    root:x:0 % 0:root:/root:/bin/bash
    daemon:x:1 % 1:daemon:/usr/sbin:/usr/sbin/nologin

    #将成功替换的内容写入到file文件里
    $ sed -n 's/qi/qiqi/w file' passwd ; cat file
    qiqi:x:1000:1000:zhuandshao,,,:/home/qi:/bin/bash





    第三部分 sed高级命令与示例

      3.1 {}

        {command1;command2;......commandn}:顺序执行多个sed命令

    示例:
    $ sed -n '{s/root/test/;1p}' passwd test:x:0:0:root:/root:/bin/bash

      3.2 &

        &:匹配整个字符串,替换时常使用    

    示例:
       
    $ sed 's/root/&123/' #使用g参数可以全部替换
    root123:x:0:0:root:/root:/bin/bash
    daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin

      3.2 (...)

         (...):匹配子字符串,与1(子字符串匹配标记,匹配到的第一个子串标记为1,第二个为2,以此类推)联合使用。替换时常使用

    使用示例见:
        数据筛选--选取用户名、UID、GID

    第四部分:实用案例

    数据筛选

      4.1  使用sed输出网卡ip地址(192.168.0.100)的几种方式:

        网卡输出信息如下:

    网卡输出信息:
    $ ifconfig 
    enp1s0: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500
            ether 28:d2:44:73:4d:64  txqueuelen 1000  (以太网)
            RX packets 90  bytes 9429 (9.4 KB)
            RX errors 0  dropped 0  overruns 0  frame 0
            TX packets 106  bytes 10301 (10.3 KB)
            TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
    
    lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
            inet 127.0.0.1  netmask 255.0.0.0
            inet6 ::1  prefixlen 128  scopeid 0x10<host>
            loop  txqueuelen 1000  (本地环回)
            RX packets 5739  bytes 313926 (313.9 KB)
            RX errors 0  dropped 0  overruns 0  frame 0
            TX packets 5739  bytes 313926 (313.9 KB)
            TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
    
    wlp2s0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
            inet 192.168.0.100  netmask 255.255.255.0  broadcast 192.168.0.255
            inet6 fe80::a67b:d8cd:4fab:56bb  prefixlen 64  scopeid 0x20<link>
            ether b8:ee:65:1f:a0:d7  txqueuelen 1000  (以太网)
            RX packets 20231  bytes 25187542 (25.1 MB)
            RX errors 0  dropped 0  overruns 0  frame 0
            TX packets 12701  bytes 1595500 (1.5 MB)
            TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

        4.1.1  使用空格分别替换ip地址前半部分以及后半部分的内容,已达到筛选出ip地址的效果

    $ ifconfig wlp2s0 | sed -n '/inet /p' | sed 's/inet //'| sed 's/net.*//'
            192.168.0.100  

        4.1.2 使用子串匹配替换:通过将ip地址标记的子串与ip输出信息替换,也就是使用192.168.0.100替换inet 192.168.0.100 netmask 255.255.255.0 broadcast 192.168.0.255 达到输出ip地址的目的。

    $ ifconfig wlp2s0 | sed -n '/inet /p' | sed 's/inet ([0-9.]+).*$/1/'
            192.168.0.100

        4.1.3 使用gawk来输出ip地址

    $ ifconfig wlp2s0 | sed -n '/inet /p' | gawk '{print $2}'
    192.168.0.100

      4.2 在passwd文件中筛选出用户名、GID、UID

    #匹配用户名:(^[a-z_-]+)
    #匹配ID:([0-9]+)

    $ sed 's/(^[a-z_-]+):x:([0-9]+):([0-9]+):.*$/ USER=1 UID=2 GID=3/' passwd USER=root UID=0 GID=0 USER=daemon UID=1 GID=1 USER=bin UID=2 GID=2 USER=sys UID=3 GID=3 USER=sync UID=4 GID=65534 USER=games UID=5 GID=60

      4.3 转换大小写

        /u /l :分别将首字母转换成大写、小写

        /U /L :分别将一查UN字符转换成大写、小写

        

        4.3.1 将用户名首字母转换成大写     

    $ sed 's/[a-z_-]+/u&/' passwd 
    Root:x:0:0:root:/root:/bin/bash
    Daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
    Bin:x:2:2:bin:/bin:/usr/sbin/nologin

        4.3.2 将文件名全部转换成大写

    $ ls *.sh | sed 's/^w+/U&/' 
    AUTO-creat-shell-script.sh
    CANSHU_SHELL.sh
    CHECK_FILE.sh
    GUI-msgbox.sh

      4.4 奇偶行输出

        4.4.1 使用n命令。n:读取下一个输入行。

    示例:
    #输出偶数行
    $ nl passwd|sed -n '{n;p}' 
         2    daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
         4    sys:x:3:3:sys:/dev:/usr/sbin/nologin
         6    games:x:5:60:games:/usr/games:/usr/sbin/nologin
         8    lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
    
    #输出奇数行
    $ nl passwd|sed -n '{p;n}' 
         1    root:x:0:0:root:/root:/bin/bash
         3    bin:x:2:2:bin:/bin:/usr/sbin/nologin
         5    sync:x:4:65534:sync:/bin:/bin/sync

        4.4.2 使用间隔输出实现奇偶行输出 

    示例:
    #输出偶数行
    $ nl passwd|sed  -n '2~2p'
         2    daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
         4    sys:x:3:3:sys:/dev:/usr/sbin/nologin
         6    games:x:5:60:games:/usr/games:/usr/sbin/nologin
         8    lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
    
    #输出奇数行
    $ nl passwd|sed  -n '1~2p'
         1    root:x:0:0:root:/root:/bin/bash
         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

      

          

  • 相关阅读:
    个人冲刺6
    个人冲刺5
    个人冲刺4
    学习进度10
    个人冲刺3
    个人冲刺2
    单词统计
    返回一个整数数组中最大子数组的和
    JavaWeb_JavaEE_命名规则 转载http://www.cnblogs.com/xwdreamer/
    软件工程作业(四则运算web界面实现)-3
  • 原文地址:https://www.cnblogs.com/zhuandshao/p/7269025.html
Copyright © 2011-2022 走看看