sed命令详解
sed是一种几乎可以应用在所有UNIX平台(包括Linux)上的轻量级流编辑器,因为sed是一种流编辑器,所以,它可以对从如管道这样的标准输入中接受的数据进行编辑。因此无需将要编辑的数据存储在磁盘上的文件中。因为可以轻易将数据管道输出到sed,所以将sed用作强大的shell脚本中长而复杂的管道很容易
sed主要是用来将数据进行选取、替换、删除、增加的命令,语法:
sed [选项] '[动作]' 文件名
选项:
-n | 一般sed命令会把所有的数据都输出到屏幕上。如果加入此选项,则只会把经过sed命令处理的行输出到屏幕上; |
-e | 允许对输入数据应用多条sed命令编辑 |
-f 脚本文件名 | 从sed脚本中读入sed操作。和awk命令的-f选项非常类似 |
-r | 在sed中支持扩展正则表达式 |
-i | 用sed的修改结果直接修改读取数据的文件,而不是由屏幕输出动作 |
动作
a\ | 追加,在当前行后添加一行或多行。当添加多行时,除最后一行外,每行末尾需要用“\”代表数据未完结 |
c\ | 行替换,用c后面的字符串替换元数据行,当替换多行时,除最后一行,每行末尾需用“\”代表数据未完结 |
i\ | 插入,在当前行前插入一行或多行。当插入多行时,除最后一行外,没行末尾需要用“\”代表数据未完结 |
d | 删除,删除指定的行 |
p | 打印,输出指定的行 |
s | 字符串替换,用一个字符串替换另一个字符串。格式为:"行范围s/旧字符串/新字符串/g" (和vim中的替换格式类似) |
大家需要注意,sed所做的修改并不会直接改变文件的内容(如果是用管道符接受的命令的输出,则连文件都没有),而是把修改的结果只显示到屏幕上,除非使用 '-i'选项才会直接修改文件
行数据操作
创建测试文本
写上行号为了后面方便操作和验证
[root@localhost tmp]# vi student.txt
[root@localhost tmp]# cat student.txt
1 xiaoming nan 18
2 danni nan 17
3 liming nan 18
4 xiaomei nv 18
5 Gao nv 23
查看指定行
举几个例子来看看sed命令到底是干什么的。假设我想查看一下student.txt文件的第二行,就可以使用动作‘p’
[root@localhost tmp]# sed '2p' student.txt
1 xiaoming nan 18
2 danni nan 17
2 danni nan 17
3 liming nan 18
4 xiaomei nv 18
5 Gao nv 23
指定输出某一行
好像上一条命令的结果看着不是很顺眼,‘p’动作确实输出了第二行的数据,但是sed命令还会把所有的数据都输出一次,这时就会看到比较奇怪的结果,那如果我想指定输出某行的数据,就需要‘-n’选项的帮助了
[root@localhost tmp]# sed -n '2p' student.txt
2 danni nan 17
这样才可以指定输出指定的行。可以这样记忆,当我们需要输出指定行的时候,需要把'-n'选项和'p'动作一起使用
删除文件中的数据
再来看看如何删除文件中的数据:
[root@localhost tmp]# sed '2,5d' student.txt
1 xiaoming nan 18
# 删除从第二行到第五行的数据,只输出了第一行
# 但是文件却没有真的没修改,这是因为没有加选项'-i',sed命令只会把修改后的结果输出到屏幕,但并不会真实修改
[root@localhost tmp]# cat student.txt
1 xiaoming nan 18
2 danni nan 17
3 liming nan 18
4 xiaomei nv 18
5 Gao nv 23
看到这条命令首先需要注意:所有的动作必须使用'单引号'包含;其次,在动作中可以使用数字代表行号,逗号代表连续行的范围。还可以使用'$'代表最后一行,如果动作是 '2,$d',则代表从第二行删除到最后一行
追加和插入数据
在来看看如何追加和插入行数据:
在指定行的下面插入数据
动作a,在指定行的下面插入数据
#在第二行下面
[root@localhost tmp]# sed '2a hello' student.txt
1 xiaoming nan 18
2 danni nan 17
hello
3 liming nan 18
4 xiaomei nv 18
5 Gao nv 23
在指定行的上面插入数据
动作i,在指定行的上面插入数据
[root@localhost tmp]# sed '2i galaxy' student.txt
1 xiaoming nan 18
galaxy
2 danni nan 17
3 liming nan 18
4 xiaomei nv 18
5 Gao nv 23
插入多行数据
如果想追加或插入多行数据,除最后一行外,每行的末尾都要加入'\',代表数据未完结
[root@localhost tmp]# sed '2i Hello \
> I \
> AM \
> NEW \
> Line' student.txt
1 xiaoming nan 18
Hello
I
AM
NEW
Line
2 danni nan 17
3 liming nan 18
4 xiaomei nv 18
5 Gao nv 23
接受和处理管道符传输的数据
再来看看如何从标准输出读取处理数据
从标准输出读取内容实现数据替换
[root@localhost tmp]# cat student.txt | sed '2c NO such person' student.txt
1 xiaoming nan 18
NO such person
3 liming nan 18
4 xiaomei nv 18
5 Gao nv 23
第二行数据变成了“查无此人”。通过这个例子,说明sed不仅可以处理文件中的数据,也可以接收和处理管道符传输的数据
sed命令在默认情况是不会直接修改文件内容的。如果我确定需要让sed命令直接处理文件的内容,则可以使用'-i'选项。不过要小心,这样非常容易误操作,在操作系统文件时需要小心谨慎
如果需要直接修改文件
[root@localhost tmp]# sed -i '2c NO such person' student.txt
[root@localhost tmp]#
[root@localhost tmp]#
[root@localhost tmp]# cat student.txt
1 xiaoming nan 18
NO such person
3 liming nan 18
4 xiaomei nv 18
5 Gao nv 23
字符串替换
'c'动作是进行整行替换的,如果仅仅想替换行中的部分数据,就要使用's'动作了。格式如下:
sed 's/旧字符串/新字符串/g' 文件名
指定行替换
替换的格式和Vim非常类似,例如:
#将第三行的18替换成81
[root@localhost tmp]# sed '3s/18/81/g' student.txt
1 xiaoming nan 18
NO such person
3 liming nan 81
4 xiaomei nv 18
5 Gao nv 23
指定行注释
如果想把某行的成绩注释掉,让它不在生效,可以这样做
指定将第五行的内容添加注释#
[root@localhost tmp]# sed '5s/^/#/g' student.txt
1 xiaoming nan 18
NO such person
3 liming nan 18
4 xiaomei nv 18
#5 Gao nv 23
同时替换多个字符串
在表达式之间用;分号隔开
将全文中的nan替换为空,将xiaomei替换为空
[root@localhost tmp]# sed 's/nan//g;s/xiaomei//g' student.txt
1 xiaoming 18
NO such person
3 liming 18
4 nv 18
5 Gao nv 23
执行多个动作
“-e”选项可以同时执行多个sed动作,当时如果只执行一个动作,也可以使用“-e”选项,但是这没有什么意义。还要注意,多个动作之间要用“;”或回车分隔,例如上一条命令也可以这样写:
将Gao替换为ChangHuan同时把第4行替换为指定行
注意:动作s是替换字符串,动作c是替换行
[root@localhost tmp]# sed -e 's/Gao/ChangHuan/g;4c 4 cyy nv 20' student.txt
1 xiaoming nan 18
NO such person
3 liming nan 18
4 cyy nv 20
5 ChangHuan nv 23