10 文本处理のsed狗带

  • sed 介绍

  • 工作原理

  • 语法

    • 参数选项:-n, -e, -r, -f, -i

    • 地址定界

    • 编辑命令

    • 查找替换

    • 空间操作

  • 练习

  • 参考文档


sed介绍

sed是一个(stream editor)。    
    1) :使用sed只能在命令行下输入编辑命令来编辑文本,然后在屏幕上查看输出    
    2) :sed每次只从文件/输入读取一行,然后对该行进行指定处理,并输出结果到屏幕
        (除非取消屏幕输出有未显示使用打印命令),然后再接着读入下一行。整个文件像流水一样被逐行处理然后逐行输出。

工作原理

sed 有两个空间(可以理解为内存空间):    
    1) pattern space 模式空间:根据“模式”及“命令”进行数据处理,类似于“加工车间”    
    2) hold space 保留空间:临时存储数据的空间,类似于“仓库”(无论处理完的、还是半成品都可以存储)

sed如何工作?

1) sed读入一行,存入pattern space;    
2) 对pattern space中的内容,按照scripts对pattern space中的内容进行处理(修改、替换、删除、追加等);    
3) 根据需要,与hold space进行数据交换(追加、覆盖、交换);    
4) 根据命令设定,将处理结果输出到STDOUT;
    (默认读入pattern space的行都会自动打印,并且即便已经找到指定行,sed依然会将文本全部过一遍  )    
5) 切换至下一行进行处理;

image1.png

语法

sed [option]... 'script' inputfile...
其中,script包含了“”、“”、“”、“”的功能,并支持 “”。

参数选项

option参数 用途说明
-n

暂停pattern space自动打印,与编辑命令中的p结合可以只打印符合条件的数据

-e script

可添加多个脚本,如sed -e 'script1' -e 'script2' file

-f script-file

将脚本文件中的内容加入script中执行

-i[suffix]

不用-i时不会修改源文件,添加后缀如.bak,会将源文件备份为file.bak,直接编辑源文件

-r

在script中使用扩展正则表达式ERE

# 打印passwd文件的第2行内容
sed -n '2p' passwd

# 使用script1中的sed命令脚本处理passwd文件
sed -f script1 passwd

# 修改passwd文件,并在修改之前将其备份为passwd.bak
sed -i.bak 'G' passwd

地址定界

(1) 不给地址:对全文进行处理
(2) 单地址            
            #       :   指定的行
    /pattern/       :  被此处模式所能够匹配到的每一行
            $       :   最后一行
(3) 地址范围    
    #,#             :   第几行到第几行 
    #,+#            :  第几行,并向后加几行
    /pat1/,/pat2/   :  模式1匹配结果所在行(第一个),到 模式2匹配结果所在行(最后一个),包含边界    
    #,/pat1/        :  第几行,到模式1匹配结果所在行(最后一个),包含边界
    addr1, ~N       :   匹配到addr1及其以后第一个行号为N的倍数的行,包含边界
(4) ~:步进    
    1~2 奇数行    
    2~2 偶数行

编辑命令

命令标识 用途说明
d 删除模式空间匹配的行(delete)
p 显示模式空间中的内容(print)
a \text 在行后面追加文本;支持使用\n实现多行追加(append)
i \text 在行前面插入文本;支持使用\n实现多行插入(insert)
c \text 替换行为单行或多行文本(change)
w /path/to/somefile 保存模式匹配的行至指定文件(write)
r /path/from/somefile 读取指定文件的文本至模式空间中匹配到的行后(read)
= 为模式空间中的行打印行号
! 模式空间中匹配行取反处理
# 在/etc/passwd中root所在行后新增一行,内容为superman
sed '/root/a\superman'  /etc/passwd
sed '/root/a superman'  /etc/passwd    ### a superman 与a\superman效果相同,但是建议使用\,i和c也有此效果

# 在/etc/passwd中root所在行前新增一行,内容为superman
sed '/root/i\superman' /etc/passwd     ### 行前

# 将/etc/passwd中root所在行替换为为superman
sed '/root/c\superman' /etc/passwd     ### 代替行

查找替换

s///:查找替换,支持使用其它分隔符,s@@@,s###替换标记:    
    g: 行内全局替换
    p: 显示替换成功的行
    w /PATH/TO/SOMEFILE:将替换成功的行保存至文件中,若文件中有内容会被覆盖,
                         但如果使用-e选项而每个命令都保存到同一个文件则是追加的形式
# 将passwd中的所有root替换成superman,所有wangcai替换成xiaobai,并将替换成功的行记录到change文件中
sed -e 's/root/superman/gw /testdir/change' -e 's/wangcai/xiaobai/gw /testdir/change' /etc/passwd

空间操作

操作标识 用途说明
h 把模式空间中的内容覆盖至保持空间中(copy pattern space to hold space)
H 把模式空间中的内容追加至保持空间中(append pattern space to hold space)
g 从保持空间取出数据覆盖至模式空间(copy hold space to pattern space)
G 从保持空间取出内容追加至模式空间(append hold space to pattern space)
x 把模式空间中的内容与保持空间中的内容进行互换(Exchange the contents of pattern space and hold space)
n 读取匹配到的行的下一行覆盖至模式空间(read the next line of input into pattern space)
N 追加匹配到的行的下一行至模式空间(append the next line of input into pattern space)
d 删除模式空间中的行(Delete pattern space. immediately start next cycle.)
D 删除当前模式空间开端至\n的内容(不再传至标准输出),放弃之后的命令,但是对剩余模式空间重新执行sed
# 在每一行后面增加一空行
sed G file

# 在每一行后增加两个空行
sed 'G;G' file

# 显示所有奇数行
sed 'n;d' file

# 显示所有偶数行
sed -n 'n;p' file

# 删除所有空行,并在每一行后面增加一个空行
sed '/^$/d;G' file

# 给每一个非空行编号,并只将非空行的行号及行内容到一行
sed '/./=' file | sed '/./N; s#\n# #'

# 取passwd文件的最后一行
sed '$!d' passwd
sed -n '$p' passwd

# 去掉文件中的空行,并为每一行后加一空行分隔
sed '/^$/d;G' FILE

# 将passwd文件逆序展示(同于 tac )
sed '1!G;h;$!d' /etc/passwd 
#---------------------------------------------------------------------------------------------------------------------------
# 命令解析:
#   1)若当前行不是第一行,则从hold space取内容追加到 pattern space的内容之后;第一行不操作;
#   2)将pattern space中的内容替换hold space中的现有内容;
#   3)若当前行不是最后一行,则清空pattern space;
# 示例说明:
#   文件共五行,内容分别为1、2、3、4、5(下文解释每个数字代表一行)
#   1)第一行,直接放入hold space,清空pattern space;                            [patternspace:null     ; holdspace:1       ]
#   2) 第二行,取holdspace内容追加到patternspace,替换holdspace,清空patternspace;[patternspace:null     ; holdspace:2 1     ]
#   3) 第三行,取holdspace内容追加到patternspace,替换holdspace,清空patternspace;[patternspace:null     ; holdspace:3 2 1   ]
#   4) 第四行,取holdspace内容追加到patternspace,替换holdspace,清空patternspace;[patternspace:null     ; holdspace:4 3 2 1 ]
#   5) 第五行,取holdspace内容追加到patternspace,替换holdspace;                 [patternspace:5 4 3 2 1; holdspace:5 4 3 2 1]
#   最后,命令执行结束,默认输出打印 “pattern space” 的内容。
#---------------------------------------------------------------------------------------------------------------------------
# 
# 在这里,我原来没有认真看帮助手册,因此对于默认打印有一个错误的认知(如下图中的结论所示所示),
#  “正确的” 结论应该是:自动打印是在命令执行完后,打印pattern space的内容。
# 
# 【关于n】
# If auto-print is not disabled,print the pattern space,then,regardless,replace the pattern space with the next line of input.
# If there is no more input then `sed' exits without processing any more commands.
# 【关于错误的重新解读】
#   下图中第3张之所以打印出第一行,是因为n的同时又未禁用掉自动打印。
#---------------------------------------------------------------------------------------------------------------------------

image2.png


练习

1、删除/etc/grub2.cfg文件中所有以空白开头的行行首的空白字符

sed -r 's@^[[:space:]]+@@' /etc/grub2.cfg
# 注意:+是必须的,因为空白开头的空白字符的个数 ≥ 1

2、删除/etc/fstab文件中所有以#开头,后面至少跟一个空白字符的行的行首的#和空白字符

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

3、在/root/install.log每一行行首增加#号

sed -r 's@(.*)@#\1@g' /root/install.logsed  's@^@#@' /root/install.log

4、在/etc/fstab文件中不以#开头的行的行首增加#号

sed 's@^[^#]@#@' /etc/fstab
sed -r 's@(.*)@#\1@g' /etc/fstab

5、处理/etc/fstab路径,使用sed命令取出其目录名和基名

echo /etc/sysconfig/ |sed -r 's#[^/]+/?$##'
echo /etc/sysconfig/ |sed -r  's#^(.*/)([^/]+/?)$#\1#'     ### 取目录名
echo /etc/sysconfig/ |sed -r  's#^(.*/)([^/]+/?)$#\2#'     ### 取基名

6、利用sed 取出ifconfig命令中本机的IPv4地址

ifconfig | sed -n 2p | sed -r 's@inet (.*) net.*@\1@'

7、统计centos安装光盘中Package目录下的所有rpm文件的以.分隔倒数第二个字段的重复次数

ls *.rpm |sed -r 's#.*\.(.*)\.rpm$#\1#'|sort|uniq -c    ### sort 默认按照ASCII码表先后排序

ls *.rpm |rev |cut -d. -f2 |rev|sort |uniq -c

参考

[1] 了解sed的工作原理(pattern space 和 hold space

[2] sed流编辑器

[3] SED单行脚本快速参考

原创文章,作者:taobaibai,如若转载,请注明出处:http://www.178linux.com/33881

(0)
taobaibaitaobaibai
上一篇 2016-08-12 14:45
下一篇 2016-08-12 16:06

相关推荐

  • SSH端口转发

      SSH 会自动加密和解密所有SSH 客户端与服务端之间的网络数据。但是,SSH 还能够将其他TCP 端口的网络数据通过SSH 链接来转发,并且自动提供了相应的加密及解密服务。这一过程也被叫做“隧道”(tunneling),这是因为SSH 为其他TCP 链接提供了一个安全的通道来进行传输而得名。例如,Telnet,SMTP,LDAP 这些TCP 应用均能够…

    2017-09-10
  • Linux-系统启动的基本过程 以及相关破环修复实验。

    这章简单描述下系统的启动流程,主要以破环修复实验为主: 系统启动基本过程:       Linux系统启动过程大致按照如下步骤进行(这是一个简述):        第一阶段:BIOS启动引导阶段;       …

    2017-07-10
  • 二、(1)Linux常用文件管理类命令详解

    Linux 文件管理 命令 cp mv rm

    2018-01-08
  • 一键搭建mysql集群系列二

    mysql 5.7  主从复制 本节是在上一节的基础之上做的操作,上节我们通过脚本实现了一键自动化安装mysql5.7,这次我们要在三台机器上部署msyql5.7,并实现主从复制,实现的宗旨是,能自动化,就尽量自动化,实在不能自动化,那就手工化 用的脚本和文件说明1.install_mysql.sh 自动化安装mysql脚本2.ntpdate.sh 时间同步…

    2017-05-21
  • 非交互式添加分区

    非交互式添加分区 方法一 添加/deb/sdb 下的分区,其实位置为1到1000M,第二个分区位置为1001至3000M,位置千万不能指定错误 parted /dev/sdb mkpart primary 1 1000M parted /dev/sdb mkpart primary 1001 3000M 方法二 (1)将你要在parted命令行输入的命令实现…

    Linux干货 2017-04-24
  • Linux源码包安装详解

    安装源码包 安装一个源码包,是需要我们自己把源代码编译成二进制的可执行文件。如果你读得懂这些源代码,那么你就可以去修改这些源代码自定义功能,然后再去编译成你想要的。使用源码包的好处除了可以自定义修改源代码外还可以定制相关的功能,因为源码包在编译的时候是可以附加额外的选项的。 源码包的编译用到了linux系统里的编译器,常见的源码包一般都是用C语言开发的,这也…

    Linux干货 2016-09-06