文本处理三剑客之 Sed ——一般编辑命令分分快三

作者:电脑系统

常用选项:

-n:不输出模式中的内容到屏幕

-e:多点编辑

-f /path/to/script_file:从指定文件中读取编辑脚本

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

-i:修改原文件

示例:

   $ sed -rn 's@^[0-9] @@p' text  #删除所有数字开头行的数字
    a
    b
    c
    d
    e
    f
    g
    h
    i


    $ sed  's@.*@#&@' text #给text文件中每一行前面加#号
    #1a
    #2b
    #3c
    #4d
    #5e
    #6f
    #7g
    #8h
    #9i

    # 删除文件中以#号开头后跟一个空白字符的行的开头的#和空白字符
    $ cat text2
    this is 1
    # this is 2
    #this is 3
    # this is 4
    this is 5

    $ sed 's@^#[[:space:]]@@' text2 
    this is 1
    this is 2
    #this is 3
    this is 4
    this is 5

    # 给text2文件中不以#开头的行的行首加#号
    $ cat text2
    this is 1
    # this is 2
    #this is 3
    # this is 4
    this is 5

    $ sed  's@^[^#].*@#&@' text2
    #this is 1
    # this is 2
    #this is 3
    # this is 4
    #this is 5


    $ echo /app/testdir/rootdir/motd/ | sed -r 's@(^/.*/)(. )/?@1@' #取目录名
    /app/testdir/rootdir/
    $ echo /app/testdir/rootdir/motd/ | sed -r 's@(^/.*/)(. )/?@2@' #取基名
    motd/

    $ ifconfig ens33| sed -rn 's@.*inet (.*) netmask.*@1@p' # 取出 ifconfig ens33命令中的ipv4地址
    192.168.5.137

编辑命令:

d:删除

p:显示

a text:在行后面追加文本;支持使用n实现多行追加

i text:在行前面插入文本;支持使用n实现多行插入

c text:替换行为单行或多行文本

w /path/to/somefile 保存模式空间匹配到的行至指定文件中

r /path/from/somefile:读取指定文件的文本流至模式空间中匹配到的行的行后

=:为模式空间中的行打印行号

!:取反

s///:替换标记,s///g行内全局替换;支持使用其它分隔符,s@@@,s###

地址定界:

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

(2) 单地址:

        #: 指定的行

        /pattern/:被此处模式所能够匹配到的每一行

(3) 地址范围

        #,#:从第#行开始到第#行结束

        #, #:从第#行开始,加#行

        #,/pat1/:从第#行开始,到第一次被模式匹配的行结束

        /pat1/,/pat2/:从被模式1匹配到的第一行开始,到被模式2匹配到的第一行结束;

        $:最后一行

(4)步进:~

        1~2:表示从1开始,步进2行,如3,5,7行即所有奇数行

        2~2:表示所有偶数行

sed介绍

sed:stream editor

是一个行编辑器,或叫流编辑器,每次处理一行,处理完一行再处理下一行。sed并不直接处理源文件,而是读取一行后放入模式空间(patten space)里,在这个模式空间中完成编辑,并输出显示。当然sed加上 –i 参数也可以直接原处理文件。sed不仅有模式空间,还有一个叫保持空间的概念,模式空间和保持空间的内容可以相互交换,覆盖,追加等,但是用的较少,用起来也比较烧脑,属于sed的高级用法。

示例:

文件text内容如下:

$ cat text
1a
2b
3c
4d
5e
6f
7g
8h
9i

$ sed -n '2p' /etc/issue #显示第二行
2b

$ sed -n '/e$/p' text #显示e结尾的行
5e

$ sed -n '4,8p' text #显示第4到第8行
4d
5e
6f
7g
8h

$ sed -n '4, 3p' text #显示第4行以及后面的3行
4d
5e
6f
7g

$ sed -n '/c$/,/^7/p' text #显示c结尾的行开始到7开头的行中的所有行
3c
4d
5e
6f
7g

$ sed -n '5,/^7/p' text #显示第五行开始到7开头的行中的所有行
5e
6f
7g

$ sed -n '2~3p' text #从第2行开始,每隔3行显示一行
2b
5e
8h

$ sed -n '1~2p' text #显示奇数行
1a
3c
5e
7g
9i

用法举例:

[root@slave ~]# cat ifcfg-ens33 
TYPE="Ethernet"
BOOTPROTO="none"
DEFROUTE="yes"
IPV4_FAILURE_FATAL="no"
IPV6INIT="yes"
IPV6_AUTOCONF="yes"
IPV6_DEFROUTE="yes"
IPV6_FAILURE_FATAL="no"
IPV6_ADDR_GEN_MODE="stable-privacy"
NAME="ens33"
UUID="3503f57e-dce7-425e-870f-efbc4897bfb2"
DEVICE="ens33"
ONBOOT="yes"
IPADDR="192.168.100.20"
PREFIX="24"
GATEWAY="192.168.100.2"
DNS1="114.114.114.114"
IPV6_PEERDNS="yes"
IPV6_PEERROUTES="yes"
IPV6_PRIVACY="no"

1.显示1到3行的内容

[root@slave sed]# sed -n '1,3p' ifcfg-ens33
TYPE="Ethernet"
BOOTPROTO="none"
DEFROUTE="yes"

2.删除第2行至最后一行

[root@slave ~]# sed '2,$d' ifcfg-ens33 
TYPE="Ethernet"

3.把192.168.100.20替换成192.168.100.30并只显示此行

[root@slave ~]# sed -n 's/192.168.100.20/192.168.100.30/;/IPADDR/p' ifcfg-ens33 
IPADDR="192.168.100.30"

4.把所有的IPV6换成ipv6

[root@slave ~]# sed -n '1,$ s/IPV6/ipv6/g;/ipv6/p' ifcfg-ens33 
ipv6INIT="yes"
ipv6_AUTOCONF="yes"
ipv6_DEFROUTE="yes"
ipv6_FAILURE_FATAL="no"
ipv6_ADDR_GEN_MODE="stable-privacy"
ipv6_PEERDNS="yes"
ipv6_PEERROUTES="yes"
ipv6_PRIVACY="no"

5.在第1行之前和第3行后面加入文本“hello sed”,并显示1到4行

[root@slave ~]# sed -ne '1 i hello sedn===============' -e '3 a ===================nhello sed' -e '1,4p' ifcfg-ens33 
hello sed
===============
TYPE="Ethernet"
BOOTPROTO="none"
DEFROUTE="yes"
===================
hello sed
IPV4_FAILURE_FATAL="no"

6.删除包含IPV6的行

[root@slave ~]# sed -e '/.*IPV6.*/d' ifcfg-ens33 
TYPE="Ethernet"
BOOTPROTO="none"
DEFROUTE="yes"
IPV4_FAILURE_FATAL="no"
NAME="ens33"
UUID="3503f57e-dce7-425e-870f-efbc4897bfb2"
DEVICE="ens33"
ONBOOT="yes"
IPADDR="192.168.100.20"
PREFIX="24"
GATEWAY="192.168.100.2"
DNS1="114.114.114.114"

7.从文件sedscript读入sed脚本,要求将BOOTPROTO=”none”改成”static”,注释掉所有包含IPV6的行,在文件开始和结束行加===sed is a strong tool===,并将网关改成192.168.100.3最后将修改后的内容保存到ifcfg-test文件中

[root@slave sed]# cat sedscript 
#!/bin/sed -f
# this is a sed script
1 i === sed is strong tool === 
s/^IPV6/# IPV6/g 
s/none/static/
s/192.168.100.2/192.168.100.3/
$ a === sed is strong tool ===
w ifcfg-test

[root@slave sed]# chmod  x sedscript 
[root@slave sed]# ./sedscript ifcfg-ens33 
[root@slave sed]# cat ifcfg-test
TYPE="Ethernet"
BOOTPROTO="static"
DEFROUTE="yes"
IPV4_FAILURE_FATAL="no"
# IPV6INIT="yes"
# IPV6_AUTOCONF="yes"
# IPV6_DEFROUTE="yes"
# IPV6_FAILURE_FATAL="no"
# IPV6_ADDR_GEN_MODE="stable-privacy"
NAME="ens33"
UUID="3503f57e-dce7-425e-870f-efbc4897bfb2"
DEVICE="ens33"
ONBOOT="yes"
IPADDR="192.168.100.30"
PREFIX="24"
GATEWAY="192.168.100.3"
DNS1="114.114.114.114"
# IPV6_PEERDNS="yes"
# IPV6_PEERROUTES="yes"
# IPV6_PRIVACY="no"

上面这个例子中的i和a插入和追加的内容没有写入到文件中,但是用重定向的方式可以。

查找替换:

s///,支持使用其它分隔符,如 s@@@,s### ,s___

替换标记:

g: 行内全局替换

p: 显示替换成功的行

w /PATH/TO/SOMEFILE:将替换成功的行保存至文件中

地址定界:

1.不给地址:对全文进行处理

2.单地址:

            #:指定的行

            /pattern/:被此模式所能匹配到的每一行

3.地址范围:

            #,#:表示从第几行到第几行

            #, #:表示第几行开始后的多少行

            /pat1/,/pat2/:表示第一次匹配到模式1,模式2的行

sed简介

sed (stream editor for filtering and transforming text) 是Linux上的文本处理三剑客之一,另外两个是grep和awk.

sed又称行编辑器,每次读取并处理一行文本.

 

sed用法

sed [option]… ‘script’ inputfile … …

命令格式

sed [option]... 'script' inputfile..

script:

sed处理文本所应用的脚本,如地址定界,编辑操作

sed的选项(options)

        -n:不自动输出模式空间的内容到屏幕

        -e script, --expression=script:实现多点编辑,

        如:

 # sed -e 's@^#[[:space:]]*@@' -e '/^UUID/d' /etc/fstab

        -f:/PATH/SCRIPT_FILE: 从指定文件中读取编辑脚本

        -r , --regexp-extended: 支持使用扩展正则表达式

        -i[SUFFIX], --in-place[=SUFFIX]:对原文件进行编辑

        -i.bak: 编辑原文件前会先创建一个 原文件名 .bak后缀的备份

 

常用一般编辑命令

d: 删除模式空间匹配的行,并立即进入下一轮循环

p:打印当前模式空间内容,追加到默认输出之后

a []text:在指定行后面追加文本,支持使用n实现多行追加

i []text:在行前面插入文本

c []text:把匹配到的行替换为单行或多行文本

w /path/somefile: 保存模式匹配的行至指定文件

r /path/somefile:读取指定文件的文本至模式空间中匹配到的行后

=: 为模式空间中的行打印行号

!:模式空间中匹配行取反处理

工作原理

1.sed命令开始执行后

2.先从文本中读取第一行,放在模式空间 (pattern space)中

3.判断这行文本是否符合指定模式,符合则进行编辑,然后把结果输出到标准输出.

4.不符合的话默认也会输出到标准输出.除非特别指定不输出不符合的结果行.

5.继续读取下一行,以此类推.

 

  • sed默认会对文件的每一行做处理.
  • 可以指定sed仅处理匹配到的行
  • 默认不对原文件进行编辑,只输出处理结果
  • 在sed的高级用法中会用到sed的另一个空间:保持空间(hold space).
  • 模式空间读进来的数据可以放进保持空间等待后续操作,两个空间的数据可以自由移动,互相覆盖或追加.

 

分分快三全天计划网站 1

sed原理简图

 

示例:

   $ cat /etc/passwd -n | sed '2,51d' #删除2-51行
         1  root:x:0:0:root:/root:/bin/bash
        52  apache:x:48:48:Apache:/usr/share/httpd:/sbin/nologin
        53  named:x:25:25:Named:/var/named:/sbin/nologin

    $ sed '2~2d' text #删除偶数行,显示奇数行
    1a
    3c
    5e
    7g
    9i

    $ df | sed -n '/^/dev/sd/p' #过滤出dev/sd开头的行
    /dev/sda2       52403200 3932216  48470984   8% /
    /dev/sda5       20961280  142872  20818408   1% /app
    /dev/sda1        1038336  161556    876780  16% /boot

    $ sed '2,4a   = = =' text #在2-4行后面分别追加自定义字符,斜线表示之后出现的所有字符都算内容.
    1a
    2b
       = = =
    3c
       = = =
    4d
       = = =
    5e
    6f
    7g
    8h
    9i

    $ sed '4i = = =' text #在第4行上方加入字符
    1a
    2b
    3c
     = = =
    4d
    5e
    6f
    7g
    8h
    9i


    $ sed '/^6/c6666' text #把第6行替换为6666
    1a
    2b
    3c
    4d
    5e
    6666
    7g
    8h
    9i

    $ sed -n '/^alias/w /app/alias.txt' ~/.bashrc #把.bashrc文件中的alias开头的行保存到/app/alias.txt中

    $ cat alias.txt 
    alias rm='rm -i'
    alias cp='cp -i'
    alias mv='mv -i'

    $ sed '/^alias/r /etc/centos-release' ~/.bashrc #把/etc/centos-release中的内容插入到.bashrc中被模式匹配到的行之后
    # .bashrc

    # User specific aliases and functions

    alias rm='rm -i'
    CentOS Linux release 7.4.1708 (Core) 
    alias cp='cp -i'
    CentOS Linux release 7.4.1708 (Core) 
    alias mv='mv -i'
    CentOS Linux release 7.4.1708 (Core) 

    # Source global definitions
    if [ -f /etc/bashrc ]; then
        . /etc/bashrc
    fi


    $ sed '/^alias/=' ~/.bashrc #在匹配到的行只上添加行号
    # .bashrc

    # User specific aliases and functions

    5
    alias rm='rm -i'
    6
    alias cp='cp -i'
    7
    alias mv='mv -i'

    # Source global definitions
    if [ -f /etc/bashrc ]; then
        . /etc/bashrc
    fi

    $ sed -n '/^alias/!p' ~/.bashrc #显示没有被匹配到的行(结果取反)
    # .bashrc

    # User specific aliases and functions


    # Source global definitions
    if [ -f /etc/bashrc ]; then
        . /etc/bashrc
    fi

    $ sed -n '/e$/!p' text #显示除了e结尾的行的所有行
    1a
    2b
    3c
    4d
    6f
    7g
    8h
    9i

 

本文由分分快三计划发布,转载请注明来源

关键词: 分分快三计划