概述
sed(Stream Editor) 命令,翻译为:流编辑器。
它主要用于文本替换、查找和替换,以及其他文本操作,例如插入、删除和搜索。使用sed
,我们可以在不打开整个文件的情况下编辑文件内容。它还支持正则表达式,使其成为更强大的文本操作工具。
虽然 sed 在某些方面类似于允许脚本编辑]的编辑器(例如 ed),但它通过只对输入进行一次遍历来工作,因此效率更高。然而,sed 真正与其他类型的编辑器区别之处在于它可以在管道中过滤文本的能力。
处理时,遍历行,把当前处理的行存储在临时缓冲区中,称为:模式空间”(pattern space),接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。然后读入下行,执行下一个循环。
命令详解
语法格式如下:
sed -option 'cmd' file
其中:
- -option 是 sed 的一些选项
- 'cmd' 是处理文本的命令,如插入、删掉、替换等
- file 是待处理的文件
option 参数
-e 参数
将脚本添加到要执行的命令中,格式如下
-e script
# 或者
--expression=script
例如,表达 1i\a new line
,表示在第1行的前面,插入 a new line
:
sed -e '1i\a new line' test.txt
# 或者
sed --expression='1i\a new line' test.txt
-e
参数后面跟的是脚本,如果要执行多个脚本,可以使用多个 -e
参数
sed -ne '4p' -ne '2p' test.txt
如果没有给出 -e
, --expression
, -f
, 或 --file
选项,则第一个非选项参数将被视为要解释的 sed 脚本。
sed -n '1i\a new line' test.txt
所有剩余的都将被视为输入文件名,如果没有指定输入文件,则读取标准输入。
-f 参数
上述如果多个脚本用多个 1-e
参数,这样脚本多的时候,比较麻烦,这个时候可以用 -f
参数,来指定文件位置。
test.sh 文件内容如下,表示在第 1 行的后面添加 hahaha
,然后打印第 2 行:
1a\hahaha
2p
```
执行命令:
sed -f test.sh test.txt
结果:
-i 参数
原地编辑文件(如果提供了后缀,则会进行备份),格式如下:
-i[后缀]
# 或者
--in-place[=后缀]
sed -e
并不会直接修改文本文件本身,只会打印处理结果。如果想要修改源文件本身,可以在 e 参数前面,加个 i 参数(之所以要在 e 参数前面加 i 参数,而不是在 e 参数后面加 i 参数,是因为 e 后面要跟表达式),这个时候不会输出,如下:
sed -ie '1i\a new line' test.txt
这个时候,目录底下会多出一个 txte 后缀的文件,这个是修改之前文件的内容,也就是备份文件
如果不想要生成备份文件,可以省略掉 e 参数,直接使用-i
,如下所示:
sed -i '1i\a new line' test.txt
-n 参数
抑制模式空间的自动打印,只打印修改的内容,格式如下
-n
# 或者
--quiet
# 或者
--silent
sed 会把行缓存到缓冲区,默认下会打印缓冲区里的行,如果只要打印修改的内容,可以使用 -n
参数
sed -n '4p' test.txt
cmd 脚本
cmd一般用单引号括起来,格式如下:
'[line num]X[options]'
- line num是指定待处理的单行或几行。如果不指定行号,即为所有行。
- X是执行的命令,如a(append)、d(delete)、i(insert)、s(search and replace)等。
- options是指某些命令后可以带额外的参数。
行前插入
使用字母 i,是单词 insert 的缩写:
# -e 是expression 的缩写,代表后面跟的时候表达式,sed 是通过表达式来处理行内容的
# 表达式用引号''括起来,1代表第一行,i是insert的缩写,表示在行前插入,\斜杆主要是把内容和参数隔开
sed -e '1i\a new line' test.txt
输出结果如下:
a new line
1
2
4
5
6
行后添加
使用字母a,是单词 append 的缩写
sed -e '4a\a new line' test.txt
在第4行后面插入
删除行
使用字母d,是单词 delete 的缩写
sed -e '4d' test.txt
第四行的内容就被删除了
整行覆盖替换
使用字母 c,是单词 copy 的缩写
sed -e '1c\ di yi hang fugai' test.txt
局部替换
使用字母 s。sed 命令最主要的表达就是这个。
# new 表是要替换的内容,old表示替换成的内容
sed -e '2s/new/old/' test.txt
结果如下
表达里的 2 表示在第 2 行替换,如果省略了这个 2,表示所有行生效。
如果不加正则表达式里的 g 标识,是单词 global 的缩写,默认只会替换第一个,因为一个单词可能会出现多次,如果要全部替换,可以用g
sed -e '2s/new/old/g' test.txt
搜索替换,并且打印,后面跟一个 /p
sed -n 's/^##\s*/\t/p' $(CurFile) | column -t -s ':'
打印一行
使用参数 p,是单词 print的缩写
sed -e '4p' test.txt
如下,打印了第四行
示例
类似grep的查找功能
类似于 grep 命令的过滤,比 grep 强在于可以指定行号。
案例01:取出文件的第3行
sed -n '3p' /etc/passwd
案例02:取出 /etc/passwd 的第2行到第5行
sed -n '2,5p' /etc/passwd
案例03:过滤出/etc/passwd中包含root的行
使用 grep 命令
使用 sed 命令实现
sed -n '/root/p' /etc/passwd
注意:sed进行过滤的时候需要使用//并且里面支持基础正则,如果需要使用扩展正则需要使用sed -r选项