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)
上一篇 2016-08-12 14:45
下一篇 2016-08-12 16:06

相关推荐

  • 磁盘管理进阶–RAID–LVM初步应用

    配置配额系统 综述   在内核中执行   以文件系统为单位启用   对不同组或者用户的策略不同 根据块或者节点进行限制 执行软限制( soft limit)硬限制( hard limit) 初始化 分区挂载选项: usrquota、 grpquota 在创建好分区后, 对/etc/fstab 进行修改 , 加入 后加进来的分区的…

    Linux干货 2016-09-01
  • lvs 基本概念

    LVS(linux virtual machine) 的简写,是一个虚拟的服务器集群系统,主要用于4层负载均衡。 宗旨: 使用集群技术和Linux操作系统实现一个高性能、高可用的服务器. 很好的可伸缩性(Scalability) 很好的可靠性(Reliability),应该还是高可用吧 很好的可管理性(Manageability…

    Linux干货 2015-09-14
  • LINUX–命令的格式、类型、别名的概述及运用

    命令格式       COMMAND [OPTIONS…] [ARGUMENTS..]      [OPTIONS..] 选项:用于启用或关闭命令的某个或某些功能                &n…

    2017-05-21
  • systemd和systemctl

    systemd:      POTS–>boot Sequence(BIOS)–>Bootloader(MBR)–>kernel(ramdisk)–>rootfs(swithroot)–>/sbin/init    &n…

    Linux干货 2016-09-22
  • RPM及YUM工具介绍及使用(上)

    写在前面 常见的计算机硬件平台大致可以为分:x86、x86_64、amd64、ppc、arm、aarch64。软件平台,在Linux界则是指不同的Linux发行版。 Linux系统中的软件(非源码)由于都是在不同的硬件+软件平台开发编译完成之后发布的,因此同一个软件会区分硬件和软件环境而有不同的软件包。在安装软件时应该选择与自己的硬件和软件平台一致的软件包进…

    Linux干货 2016-12-26
  • sed工具的基本用法

    sed -n(不输出模式,不自动打印) sed -d(删除匹配到的内容) sed-e(多点编辑) sed-r(支持扩展正则表达式) sed#,#(地址定界,在此范围中匹配) sed 1~2   sed 2~2 (找奇数行和偶数行) sed =(为打印到的内容编辑行号)  sed!(取反) sed s///(查找替换,支持使用其他…

    Linux干货 2017-05-02