sed命令简介,


sed处理时,有2个缓冲区:【pattern space】和【hold space】

sed执行过程:

先读入一行,去掉尾部换行符,存入【pattern space】,执行编辑命令。 处理完毕,除非加了-n参数,把现在的【pattern space】打印出来,在后边打印曾去掉的换行符。 把【pattern space】置空。 接着读下一行,处理下一行。

sed的默认输出:【pattern space】里的内容输出到标准输出。

常用选项:

  • 【pattern space】里的内容不输出到标准输出:-n

  • 默认只能执行一个脚本,执行多个脚本:-e script, --expression=script

    可以有多个-e script

  • 如果要执行的脚本特别多,可以指定一个脚本文件:-f /path/to/sed_scirpt

    脚本文件里,每行一个编辑命令。

  • 支持使用扩展的正则表达式,默认是基本正则表达式:-r

  • 直接编辑原文件:-i

地址定界:

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

2,单地址

  • #:指定行
  • /pattern/:被此模式所匹配到的每一行

3,地址范围

  • $:最后一行

  • #,#:起始和结束
  • #,+#:起始,和从起始加多少行
  • #,/pat1/:起始到,pat1匹配到的行
  • /pat1/,/pat2/:pat1匹配到的行,到pat2匹配到的行

4,步进:~

  • 1~2:1,3,5,7,9.。。行(所有奇数行)
  • 2~2:2,4,6,8,10.。。行(所有偶数行)

编辑命令:

如果有多个命令,则用分号分隔。

  • 删掉【pattern space】里的内容:d

    删除/etc/fstab的第一行到第五行。

    # sed '1,5d' /etc/fstab
  • 打印【pattern space】里的内容:p

    乍一看是打印奇数行,但实际是把偶数行打印了出来,而且奇数行打印了2遍。
    # sed '1~2p' /etc/fstab
    使用-n禁止sed的默认行为后,就是打印奇数行了
    # sed -n '1~2p' /etc/fstab
  • 在行前插入:-i \text 支持使用\n实现多行插入

    # sed '3a \new line\nother line' /etc/fstab
    
    #
    # /etc/fstab
    new line
    other line
    在UUID行前加一段注释:
    # sed '/^UUID/i \#this is base for UUID' /etc/fstab
    #this is base for UUID
    UUID=3d3b316a-529e-484a-9895-e785fdde5365 /boot   xfs     defaults        0 0
  • 在行后插入:-a \text 支持使用\n实现多行插入

    # sed '3i \new line\nother line' /etc/fstab
    
    #
    new line
    other line
    # /etc/fstab
  • 替换行:-c \text 把匹配到的行,替换成text

    把以UUID开头的行,整行替换成text。

    # sed '/^UUID/c \#this is base for UUID' /etc/fstab
  • 保存匹配到的行,到指定文件中:-w /path/to/save

    把不以#号开头的行,保持到/tmp/fsnew

    # sed -n '/^[^#]/w /tmp/fsnew' /etc/fstab
  • 把指定文件中的内容插入到匹配行的后面:-r /path/to/insert

    在/etc/fstab的第三行的后面,插入/tmp/tst的内容。

    # cat /tmp/tst
    aaa
    bbb
    [root@localhost ~]# sed '3r /tmp/tst' /etc/fstab
    
    #
    # /etc/fstab
    aaa
    bbb
  • 在匹配到的行的上一行,加上行号:=

    在以UUID开头的行的上一行加上行号

    # sed '/^UUID/=' /etc/fstab
    
    #
    # /etc/fstab
    # Created by anaconda on Fri Nov 29 16:44:28 2019
    #
    # Accessible filesystems, by reference, are maintained under '/dev/disk'
    # See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
    #
    /dev/mapper/centos-root /                       xfs     defaults        0 0
    10
    UUID=3d3b316a-529e-484a-9895-e785fdde5365 /boot     xfs     defaults        0 0
  • 匹配到的行不执行后面的命令;没匹配到的行执行后面的命令:!。注意:!处理命令之前。

    删除不以#开头的行:

    # sed '/^#/!d' /etc/fstab
    #
    # /etc/fstab
    # Created by anaconda on Fri Nov 29 16:44:28 2019
    #
    # Accessible filesystems, by reference, are maintained under '/dev/disk'
    # See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
    #
  • 查找替换:s/要替换的/替换成的/替换标记。它的分隔符/可以自己指定,常用的有s@@@,s###

    替换标记:

    • 全局替换:g
    • 将替换成功的结果保存到文件:w /path/to/save
    • 显示替换成功的行:p

练习

1,删除test文件中所有以空白字符开头的行的行首的所有空白字符

# cat test
   11
222
   333
\+:匹配前面的次数为大于等于1
# sed 's@^[[:space:]]\+@@' test
11
222
333
# sed -n 's@^[[:space:]]\+@@p' test
11
333

2,删除/etc/fstab文件中所有以#开头的行的行首的#号及#后面所有空白字符

# sed 's@^#[[:space:]]*@@' /etc/fstab

3,删除/etc/fstab文件中所有以#开头的行的行首的#号及#后面所有空白字符,和删除所有以UUID开头的行

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

4,输出一个绝对路径给sed命令,取出其目录部分,其行为类似dirname

message后面如果有/就匹配不成功了。
# echo "/var/log/messages" | sed 's@[^/]\+$@@'
/var/log/
message后面即使有/也能匹配:非/

[^/]:非/
\+:至少一个
/\?:/有0个或者1个
# echo "/var/log/messages/" | sed 's@[^/]\+/\?$@@'
/var/log/
message后面即使有/也能匹配
由于使用了-r(扩展正则表达式),+和?前面的\可以省略了。
# echo "/var/log/messages/" | sed -r 's@[^/]+/?$@@'
/var/log/
[root@localhost ~]#

高级编辑命令

  • 把【pattern space】空间中的内容覆盖到【hold space】空间:h
  • 把【pattern space】空间中的内容追加到【hold space】空间,然后删除【pattern space】空间中的内容:H
  • 把【hold space】空间中的内容覆盖到【pattern space】空间:g
  • 把【hold space】空间中的内容追加到【pattern space】空间,然后删除【hold space】空间中的内容:G
  • 互换【hold space】【pattern space】里的内容:x
  • 把匹配到的行的下一行放入【pattern space】,并把匹配到的行删除掉:n
  • 把匹配到的行的下一行放入【pattern space】,不删除匹配到的行:N
  • 删除【pattern space】空间中的行:d
  • 删除多行模式下【pattern space】里的所有行。(比如用N了,【pattern space】里就有多行):D

1,显示偶数行:

执行过程:先把第一行读入到了【pattern space】,后面的命令的n。n的意思是读下一行,并删除当前【pattern space】里的内容后,再把下一行的内容放入【pattern space】;接下来的命令是p,p就是把当前【pattern space】里的内容输出到标准输出,所有第二行就打印到了标准输出了。然后读第3行,后面的命令是n,就再读一行,以此类推。

# sed -n 'n;p' /etc/fstab

2,倒置文本:

参看:https://blog.csdn.net/itsenlin/article/details/21129405

执行过程:先把第一行读入到了【pattern space】,发现第一行的命令是1!G,所以不做处理;接着是h,则把【pattern space】的内容,覆盖到【hold space】;接着是命令$!d,因为不是最后一行,所以执行d命令,删除【pattern space】里的内容。

读第二行到【pattern space】,发现命令是1!G,由于不是第1行了,所以执行G命令,把hold space】的内容追加到了【pattern space】,这时【pattern space】里放的是第二行和第一行的内容,而且第二行在第一行的前面。接着是$!d,由于不是最后一行,所以执行d命令,删除【pattern space】里的内容。

# cat test
   11
222
   333
最后一行,没有执行d,而且【pattern space】里的内容,而且没有使用-n,所以就把倒叙打印到标准输出了。
# sed '1!G;h;$!d' ./test
   333
222
   11

也可以用下面的命令,实现倒置。

由于没有使用d命令,所以【pattern space】里一直有内容,所以就必须用-n,最后一次用p命令把【pattern space】里的内容输出到标准输出。

# sed -n '1!G;h;$p' test

3,取出最后一行:

# sed '$!d' /etc/fstab

4,取出最后二行:

# sed '$!N;$!D' test

5,删除原有的所有空白行,而后为所有的非空白行添加一个空白行

# cat test
   11
空行
空行
222
空行
空行
   333
444
  555
666
# sed '/^$/d;G' test
   11
空行
222
空行
   333
空行
444
空行
  555
空行
666
空行

6,显示奇数行

# sed 'n;d' /etc/fstab

7,在每一行后面添加一个空白行

# sed 'G' /etc/fstab

8,练习H和g的用法:

# cat t2
one
two
three
# sed 'H;g' t2
一个空行
one
一个空行
one
two
一个空行
one
two
three

图解:H是往hold space里追加,hold space里,其实是有一个换行的。所以第一次把one加到hold space后,one的前一行就是空行。

c/c++ 学习互助QQ群:877684253

本人微信:xiaoshitou5854

相关内容

    暂无相关文章