-
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) 切换至下一行进行处理;
语法
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的同时又未禁用掉自动打印。 #---------------------------------------------------------------------------------------------------------------------------
练习
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