追忆似水流年sed

sed是一种非交互式的流编辑器,默认情况下并不会修改源文件内容,只是把命令的结果输出
处理单位:行
功能:查找替换、添加、插入、删除
适用场景:常规编辑器难以胜任的文本;大文件(几百兆);有规律的文本修改操作(全文替换)
基本语法:sed [options] 'command' file

使用-e参数和分号连接多编辑命令,它会将下一个字符串解释为sed编辑命令,在多个编辑命令时比较常用
sed -e 's/ping/notping/g' -e '/ok/notok/g' 2018-06-06

1.删除
[root@localhost ~]# cat test
110.16.101.33 can ping!
110.16.101.34 can ping!
110.16.101.35 can ping!
110.16.101.36 can ping!
110.16.101.37 can ping!
110.16.101.38 can ping!
110.16.101.39 can ping!
110.16.101.40 can ping!
110.16.101.41 can ping!
110.16.101.42 can ping!

删除第一行
[root@localhost ~]# sed '1d' test
110.16.101.34 can ping!
110.16.101.35 can ping!
110.16.101.36 can ping!
110.16.101.37 can ping!
110.16.101.38 can ping!
110.16.101.39 can ping!
110.16.101.40 can ping!
110.16.101.41 can ping!
110.16.101.42 can ping!

如果想要使修改生效,你可以采用重定向或者-i参数
[root@localhost ~]#sed '1d' test >> test
[root@localhost ~]# sed -i '1d' test

删除指定范围的行
[root@localhost ~]# sed '1,5d' test
110.16.101.38 can ping!
110.16.101.39 can ping!
110.16.101.40 can ping!
110.16.101.41 can ping!
110.16.101.42 can ping!

删除最后一行
[root@localhost ~]# sed '$d' test
110.16.101.33 can ping!
110.16.101.34 can ping!
110.16.101.35 can ping!
110.16.101.36 can ping!
110.16.101.37 can ping!
110.16.101.38 can ping!
110.16.101.39 can ping!
110.16.101.40 can ping!
110.16.101.41 can ping!

只保留第五行
[root@localhost ~]# sed '5!d' test
110.16.101.37 can ping!

删除包含ping的行
[root@localhost ~]# sed '/ping/d' test
[root@localhost ~]#

删除空行
[root@localhost ~]# sed '/^$/d' test
110.16.101.33 can ping!
110.16.101.34 can ping!
110.16.101.35 can ping!
110.16.101.36 can ping!
110.16.101.37 can ping!
110.16.101.38 can ping!
110.16.101.39 can ping!
110.16.101.40 can ping!
110.16.101.41 can ping!
110.16.101.42 can ping!

2.查找替换
s

默认情况下只替换每一行第一次匹配到的内容
[root@localhost ~]# sed 's/ping/PING/' test
110.16.101.33 can PING!ping
110.16.101.34 can PING!ping
110.16.101.35 can PING!ping
110.16.101.36 can PING!ping
110.16.101.37 can PING!ping
110.16.101.38 can PING!ping
110.16.101.39 can PING!ping
110.16.101.40 can PING!ping
110.16.101.41 can PING!ping
110.16.101.42 can PING!ping

把每行的第二个ping进行替换
[root@localhost ~]# sed 's/ping/PING/2' test
110.16.101.33 can ping!PING
110.16.101.34 can ping!PING
110.16.101.35 can ping!PING
110.16.101.36 can ping!PING
110.16.101.37 can ping!PING
110.16.101.38 can ping!PING
110.16.101.39 can ping!PING
110.16.101.40 can ping!PING
110.16.101.41 can ping!PING
110.16.101.42 can ping!PING

把每行所有的ping替换
[root@localhost ~]# sed 's/ping/PING/g' test
110.16.101.33 can PING!PING
110.16.101.34 can PING!PING
110.16.101.35 can PING!PING
110.16.101.36 can PING!PING
110.16.101.37 can PING!PING
110.16.101.38 can PING!PING
110.16.101.39 can PING!PING
110.16.101.40 can PING!PING
110.16.101.41 can PING!PING
110.16.101.42 can PING!PING

把开头110的替换掉
[root@localhost ~]# sed 's/^110/120/g' test
120.16.101.33 can ping!ping
120.16.101.34 can ping!ping
120.16.101.35 can ping!ping
120.16.101.36 can ping!ping
120.16.101.37 can ping!ping
120.16.101.38 can ping!ping
120.16.101.39 can ping!ping
120.16.101.40 can ping!ping
120.16.101.41 can ping!ping
120.16.101.42 can ping!ping

3.字符转换
使用y命令可进行字符转换,其作用为将一些列字符逐个地变换为另外一系列字符,注意长度要相同,基本用法如下:
[root@localhost ~]# cat test1
green
1234

[root@localhost ~]# sed 'y/1234/5678/' test1
green
5678
[root@localhost ~]# sed 'y/green/black/' test1
blaak
1234

4.插入文本
使用i或a命令插入文本,i代表在匹配行之前插入,a代表在匹配行之后插入
[root@localhost ~]# sed '2 i test' test
110.16.101.33 can ping!ping
test
110.16.101.34 can ping!ping
110.16.101.35 can ping!ping
110.16.101.36 can ping!ping
110.16.101.37 can ping!ping
110.16.101.38 can ping!ping
110.16.101.39 can ping!ping
110.16.101.40 can ping!ping
110.16.101.41 can ping!ping
110.16.101.42 can ping!ping

[root@localhost ~]# sed '2 a check' test
110.16.101.33 can ping!ping
110.16.101.34 can ping!ping
check
110.16.101.35 can ping!ping
110.16.101.36 can ping!ping
110.16.101.37 can ping!ping
110.16.101.38 can ping!ping
110.16.101.39 can ping!ping
110.16.101.40 can ping!ping
110.16.101.41 can ping!ping
110.16.101.42 can ping!ping

5.读入文本
[root@localhost ~]# cat test1
green

1234

从test读取文本并插入到test1的空行之后
[root@localhost ~]# sed '/^$/r test' test1
green

110.16.101.33 can ping!ping
110.16.101.34 can ping!ping
110.16.101.35 can ping!ping
110.16.101.36 can ping!ping
110.16.101.37 can ping!ping
110.16.101.38 can ping!ping
110.16.101.39 can ping!ping
110.16.101.40 can ping!ping
110.16.101.41 can ping!ping
110.16.101.42 can ping!ping
1234

6.打印
使用p命令可进行打印,但必须加上-n参数,表示不打印不相关的行,因为我们只需要匹配行的处理结果而无需整个问本内容的打印。

打印第一行
[root@localhost ~]# sed -n '1p' test
110.16.101.33 can ping!ping

在使用s命令时,替换的是第一行的33,但是打印时,则全部打印出来了
[root@localhost ~]# sed 's/33/10/' test
110.16.101.10 can ping!ping
110.16.101.34 can ping!ping
110.16.101.35 can ping!ping
110.16.101.36 can ping!ping
110.16.101.37 can ping!ping
110.16.101.38 can ping!ping
110.16.101.39 can ping!ping
110.16.101.40 can ping!ping
110.16.101.41 can ping!ping
110.16.101.42 can ping!ping

加上p命令就不一样
[root@localhost ~]# sed -n 's/33/10/p' test
110.16.101.10 can ping!ping

7.写文件
w命令将结果另存为
格式:sed -n 'w 目标文件' 源文件
[root@localhost ~]# sed -n '3,4 w test2' test
[root@localhost ~]# cat test2
110.16.101.35 can ping!ping
110.16.101.36 can ping!ping

8.sed脚本
调用-f参数指定脚本
[root@localhost ~]# cat sed.rules
s/110/120/g
/^$/d
[root@localhost ~]# sed -f sed.rules test
120.16.101.33 can ping!ping
120.16.101.34 can ping!ping
120.16.101.35 can ping!ping
120.16.101.36 can ping!ping
120.16.101.37 can ping!ping
120.16.101.38 can ping!ping
120.16.101.39 can ping!ping
120.16.101.40 can ping!ping
120.16.101.41 can ping!ping
120.16.101.42 can ping!ping


9.高级替换
n:读取匹配行的下一行,然后再用n命令后的编辑指令来处理该行
test文件中有一行空白行,现在想将该空行的下一行中的110该为120,而文本中的其他部分保持不变。
[root@localhost ~]# sed '/^$/{n;s/110/120/}' test
110.16.101.33 can ping!ping
110.16.101.34 can ping!ping

120.16.101.35 can ping!ping
110.16.101.36 can ping!ping
110.16.101.37 can ping!ping
110.16.101.38 can ping!ping
110.16.101.39 can ping!ping
110.16.101.40 can ping!ping
110.16.101.41 can ping!ping
110.16.101.42 can ping!ping

将模式空间的内容放入存储空间以便接下来的编辑,为了实现该功能,需要引入H/h/G/g这四个命令,这几个命令都是用于模式空间和存储空间的转换的

模式空间:当前输入行的缓冲区
存储空间:模式空间以外的一个预留缓冲区

H:将模式空间的内容追加到存储空间
h:将模式空间的内容复制到存储空间,覆盖原有存储空间
G:将存储空间的内容追加到模式空间
g:将存储空间的内容复制到模式空间

示例:实现第一行与第二行以及第三行与第四行的反转
[root@localhost ~]# cat test3
a
b
aa
bb
[root@localhost ~]# sed '/a/{h;d};/b/G' test3
b
a
bb
aa


sed总结
1.常用命令
a 在匹配行后面加入文本
c 字符转换
d 删除行
D 删除第一行
i 在匹配行前面加入文本
h 将模式空间的内容复制到存储空间,覆盖原有存储空间
H 将模式空间的内容追加到存储空间
g 将存储空间的内容复制到模式空间
G 将存储空间的内容追加到模式空间
n 读取下一个输入行,用下一个命令处理新的行
N 追加下一个输入行到模版块后并在二者间插入新行
p 打印匹配的行
P 打印匹配的第一行
q 退出sed
r 从外部文件读取文本
w 追加写文件
! 匹配的逆
s/old/new/ 用new替换正则表达式old

2.常用参数
-e 多条件编辑
-h 帮助信息
-n 不输出不匹配的行
-f 指定sed脚本
-V 版本信息
-i 直接修改原文件

3.常用的sed常用的正则表达式匹配
元字符
^ 匹配行的开始
$ 匹配行的结束
. 匹配任一非换行字符
* 匹配零个或任意多个字符
[] 匹配指定范围内的字符
[^] 匹配不在指定范围内的字符
() 保存匹配字符
& 保存搜索字符用来替换其他字符,比如s/love/**&**/,love变成**love**
< 锁定单词的开始
> 锁定单词的结束
x{5} 重复字符串x5次
x{5,} 重复字符串x至少5次
x{5,10} 重复字符串x5-10次

原文地址:https://www.cnblogs.com/liangjiongyao/p/9304063.html