sed
是在命令行环境使用的编辑器,它可以不依赖交互界面来完成一些文本的编辑操作,适合在自动化脚本中用来修改配置文件;或者在缺少界面编辑器的情况下使用,比如很多容器中,连 Vim
都没有,但 sed
小巧,不太占用存储空间,一般是标配。
sed
虽小,却可以完成各种复杂的编辑操作,它的使用教程写一本书都不过分。本文篇幅有限,希望通过一些基于 行
的 增删改
的例子,助你掌握 sed
的基本用法,以应对大部分编辑文件的场景。
首先,使用以下命令创建一个名称为 file1
的文件并写入几行文本:
echo "Hello world" > file1
echo "Hello chaos world" >> file1
echo "Bye" >> file1
运行 cat file1
,查看 file1
文件内容,显示如下:
Hello world
Hello chaos world
Bye
基本用法:sed [选项] 命令 文件名
sed
是基于行
的编辑器,通过命令逐行编辑内容,编辑后的结果默认会直接输出,不保存到文件。如果需要将结果保存到文件,加上 -i
选项即可。以下示例都是直接输出。
d
命令,删除行
sed 'd' file1
这个例子中,d
命令会应用到每一行,即删除每一行,所以最终输出结果为空。如果想要删除指定的行,可以在 d
命令前面加入行号;或者指定起始行和终止行,以 ,
分隔。例如:
# 删除第 2 行
sed '2d' file1
# 删除 1~3 行
sed '1,3d' file1
i
、a
命令,插入与追加新行
# 在第 2 行之前插入内容
sed '2i prepended line' file1
# 在第 2 行之后追加内容
sed '2a appended line' file1
macOS / osx 自带的 POSIX 版 sed 不允许这样插入或者追加新行,建议安装 GNU 版 sed,然后使用 gsed
命令代替 sed
。使用 brew 来安装 gnu-sed :
brew install gnu-sed
s
命令,字符串的查找替换
# 将所有行的 "Hello" 替换为 "Hi"
sed 's/Hello/Hi/' file1
类似的,也可以在指定的行进行查找替换。另外,支持使用正则表达式查找,比如:
# 将第 2 行的第 1 个字符替换为空
sed '2s/^.//' file1
# 分隔符并非一定是 "/" ,例如可以使用 "!" 来分隔:
sed '2s!^.!!' file1
比较常见的场景如:给配置文件某一行添加注释或去掉注释
# 给第 2 行加上 '#'
sed '2s/^/#/' file1
# 去掉第 2 行行首的 '#'
sed '2s/^#//' file1
p
命令,打印行
# 打印出包含 "world" 的行
sed '/world/p' file1
输出结果如下:
Hello world
Hello world
Hello chaos world
Hello chaos world
Bye
结果是不是和预期的不一样?由于 sed 是基于行处理的,默认会将每一行处理后的结果输出,在没有任何命令的情况下,相当于逐行输出了整个文件内容;我们同时使用了 p
命令对包含 "world" 的行打印了一次,所以符合查找的行最终都被打印了两遍。解决办法很简单,只要带上 -n
选项,就会关闭默认输出:
sed -n '/world/p' file1
使用 r
命令读取标准输出的内容
这个命令稍微复杂一些。如果了解管道、标准输出和标准输入的概念,还可以将其他程序的输出结果追加到目标文件的指定位置:
# 将 echo 输出的内容追加到 file1 文件的第一行后面
echo "appended line" | sed '1r /dev/stdin' file1
甚至可以交互式在指定位置插入内容,这个比较实用,值得一试:
cat <<EOF | sed '2r /dev/stdin' file1
# 输入内容,可以是多行,结束输入后内容就会追加至第 2 行
# 如何结束输入?换行后输入 EOF 并敲回车
我们还可以借用 diff
命令预览一下我们的修改:
echo "appended line" | sed '1r /dev/stdin' file1 | diff -u file1 -
可以清楚地展示出变动的部分:
@@ -1,3 +1,4 @@
Hello world
+appended line
Hello chaos world
Bye
总结
以上介绍了 sed
的常用命令:
-
d
删除行 -
s
查找替换 -
i
,a
插入与追加 -
p
打印行 -
r
追加从文件中读取的内容,常用来读取标准输入/dev/stdin
以及它的选项:
-
-i
将结果保存到文件 -
-n
关闭默认输出
这只是其中一小部分命令与选项,但是熟练掌握这些就足以应对常规的编辑任务。另外,你可以对同一行使用多个命令,支持同时编辑多个文件,如果熟知管道、正则表达式就更好了,能完成较为复杂的编辑操作。
其实,你不必等到精通 sed
才去使用它。