0%

行上动刀的 sed

行上动刀的 sed

.. _linux_sed_beginner:

.. note::
工欲善其事,必先利其器。
《论语·卫灵公》

批量改配置、替换日志里的一串字、删掉匹配的行——不愿开编辑器逐行点的时候,sed 就是那把流上动刀的剪刀。名字来自 stream editor:数据从管道流过,规则碰上了就改,默认改完的结果打到标准输出,原文件安然不动(除非你显式要求原地写入)。

sed 的官方定义为:

sed - stream editor for filtering and transforming text

命令格式

1
$ sed [选项] '脚本' [文件...]

入门最常用的脚本形态是替换:

1
$ sed 's/旧/新/' 文件

替换字符串

假定有文件 app.conf

1
2
3
4
$ cat app.conf
listen=127.0.0.1
port=8080
debug=true

8080 换成 9090(只改每行第一处匹配):

1
2
3
4
$ sed 's/8080/9090/' app.conf
listen=127.0.0.1
port=9090
debug=true

一行里可能出现多次时,加 g 做全局替换:

1
2
$ echo 'aa-aa-aa' | sed 's/aa/bb/g'
bb-bb-bb

删除匹配的行

删掉含 debug 的行:

1
2
3
$ sed '/debug/d' app.conf
listen=127.0.0.1
port=8080

只打印匹配行(有点像 grep 的亲戚):

1
2
$ sed -n '/listen/p' app.conf
listen=127.0.0.1

原地修改要谨慎

-i 会直接改文件。备份习惯值得养成:

1
$ sed -i.bak 's/8080/9090/' app.conf

会生成 app.conf.bak,改错了还能找回。没有把握时,先不加 -i,盯着标准输出确认无误再动手。

DOS 文本偶发的 \r,也可以顺手清掉行尾那个多余字符:

1
$ sed 's/\r$//' dos.txt > unix.txt

更花哨的多表达式、分组引用,等这几招用顺了再加;日常运维里,s///d-n/p-i 四板斧已经够用很久。

处无为之事,行不言之教;作而弗始,生而弗有,为而弗恃,功成不居!