Linux sed命令学习心得

sed 实用工具按顺序逐行将文件读入到内存中。然后,它执行为该行指定的所有操作,并在完成请求的修改之后将该行放回到内存中,以将其转储至终端。完成了这一行上的所有操作之后,它读取文件的下一行,然后重复该过程直到它完成该文件。sed 默认读取整个文件并对其中的每一行进行修改,不过可以按需要将操作限制在指定的行上。 有两点十分重要:源文件(默认地)保持不被修改;输出可以被重定向到另一文件中,以保存变化。

网上看的使用语法是这样的:

sed [options] \'{command}\' [filename] [ > output_file]

但我在本地测试的时候,command那块的 \ 提示报错,把 \'{command}\' 换成 '{command}' 就没问题了,所以后面的命令都把 \ 去掉了。

进行简单修改: ‘s/old value/new value/’

[root@localhost etc]# echo 1 2 3 | sed 's/2/3/'

1 3 3

如果需要对同一行进行多次修改,推荐的方法是:

[root@localhost etc]# echo 1 2 3 4 5 | sed '
> s/2/3/
> s/4/5/
> '

1 3 3 5 5

把命令拆分为多行,每一行以 / 标志结束,最后 ' 闭合所有命令。

进行全局修改:sed在找到一个要修改的项目并作了修改之后继续处理下一行,而不继续读入该行剩余部分。当修改目标是整行时,需要使用全局修改:

[root@localhost etc]# echo 1 2 3 2 4 5 | sed 's/2/3/'

1 3 3 2 4 5

[root@localhost etc]# echo 1 2 3 2 4 5 | sed 's/2/3/g'

1 3 3 3 4 5

有条件地进行修改:

现有如下文件

[root@localhost root]# cat sample 

one 1
two 1
three 1
one 1
two 1
two 1
three 1

要将 two 后面的 1 改为 2 ,three 后面的 1 改为 3 :

[root@localhost root]# sed '
> /two/ s/1/2/
> /three/ s/1/3/
> ' sample

one 1
two 2
three 3
one 1
two 2
two 2
three 3

将修改输出至新的文件保存:

[root@localhost root]# sed '/two/ s/1/2/; /three/ s/1/3/' sample >sample_one
[root@localhost root]# cat sample_one 
one 1
two 2
three 3
one 1
two 2
two 2
three 3

使用预编写的脚本对指定文件进行处理:

[root@localhost root]# cat sedlist 
/two/ s/1/2/
/three/ s/1/3/
[root@localhost root]# sed -f sedlist sample
one 1
two 2
three 3
one 1
two 2
two 2
three 3

需要注意的是,无论是sedlist文件还是sed命令中,都不需要带有''这一对单引号。

对指定行进行处理:

只对5 ,6两行的1进行替换

[root@localhost root]# sed '5,6 s/1/2/' sample
one 1
two 1
three 1
one 1
two 2
two 2
three 1

sed默认把文件的每一行都打印到屏幕上,而sed -n则覆盖所有的显示,不向屏幕输出。但-n和-p的联合使用,结果就是只显示修改过的行:

[root@localhost root]# cat sedlist 
/two/ s/1/2/p
/three/ s/1/3/p
[root@localhost root]# sed -n -f sedlist sample
two 2
three 3
two 2
two 2
three 3

从上面可以看到,“one 1”因为没有修改所以不显示。

另一种用法是只显示一定数量的行,如2~6行:

[root@localhost root]# sed -n '2,6p' sample
two 1
three 1
one 1
two 1
two 1

删除行的语法是 '{条件} d',如果想要删除某个单词,可以考虑把它替换为空的做法: 's/cat//'

把文件中带有 two 的行删除:

[root@localhost root]# sed '/two/ d' sample
one 1
three 1
one 1
three 1

删除包含two以外的所有行:

[root@localhost root]# sed '/two/ !d' sample
two 1
two 1
two 1

删除文件的前三行:

[root@localhost root]# sed '1,3 d' sample
one 1
two 1
two 1
three 1

删除的部分特殊用法:

删除以 two 开头的行:

sed '/^two/ d' sample_one

删除以 two 结尾的行:

sed '/two$/ d' sample_one

删除文件中的空行:

sed '/^$/ d' sample

删除一篇文章中的标题可以采用下面的语法:

sed '1,/^$/ d' filename

添加和插入文本:

结合使用sed和 a,$ 选项在文章末尾添加内容:

[root@localhost root]# sed '$a 123123123123' sample
one 1
two 1
three 1
one 1
two 1
two 1
three 1
123123123123

如果要把内容添加到第三行之后,方法是:

[root@localhost root]# sed '3a cccccccc' sample
one 1
two 1
three 1
cccccccc
one 1
two 1
two 1
three 1

除了添加这个方法外,还有插入(-i)这个选项。比如把内容插入到第三行:

[root@localhost root]# sed '3i cccccccc' sample
one 1
two 1
cccccccc
three 1
one 1
two 1
two 1
three 1

在对文件修改的过程中,还可以同步进行读写另外一个文件:

[root@localhost root]# sed '/two/ s/1/2/; /three/ s/1/3/; 1,3 w sample_two' sample
one 1
two 2
three 3
one 1
two 2
two 2
three 3
[root@localhost root]# cat sample_two 
one 1
two 2
three 3

上面的命令在替换two和three对应1的同时,把修改后的1~3行输出到sample_two中。

sed除了替换功能外,还有修改功能(-c)。替换是对于单个项目而言,修改则是对于整行而言。

[root@localhost root]# echo two two | sed '/two/c dddddddd'
dddddddd
[root@localhost root]# echo two two | sed 's/two/dddddddd/'
dddddddd two
[root@localhost root]# echo two two | sed 's/two/dddddddd/g'
dddddddd dddddddd

上面三个命令很好解释了它们的区别。

提前退出:sed不一定要在扫描所有文件过后才退出,比如只查看前5行:

[root@localhost root]# sed '5q' sample
one 1
two 1
three 1
one 1
two 1

或是满足一定条件后才退出(匹配到three后退出):

[root@localhost root]# sed '/three/q' sample
one 1
two 1
three 1

还有一些特殊情况,比如将sample文件里面two替换成three,three替换成four:

[root@localhost root]# sed 's/two/three/; s/three/four/' sample
one 1
four 1
four 1
one 1
four 1
four 1
four 1

如果按照上面命令执行,会发现所有的two和three都变成了four,不符合我们的要求。

[root@localhost root]# sed 's/three/four/; s/two/three/' sample
one 1
three 1
four 1
one 1
three 1
three 1
four 1

但是把两行处理相反后,则满足要求了。当执行这种操作时,必须非常用心地注意指定操作的方式,并按某种顺序来安排它们,使得操作之间不会互相影响。

« 返回