sed 流编辑器

sed 是 Stream Editor 的缩写,意为流编辑器。它按行处理文本,可以对文本进行替换、删除、插入等操作。sed 最大的特点是可以在不打开文件的情况下直接修改内容,非常适合批量处理。

基本语法

sed [选项] '命令' 文件

常用选项:

选项含义
-n抑制默认输出
-e执行多个命令
-i直接修改文件
-r使用扩展正则

替换操作

替换是最常用的功能,语法是 s/原字符串/新字符串/标志

sed 's/old/new/' file.txt
sed 's/error/ERROR/g' app.log
sed 's/foo/bar/2' file.txt

常用标志:

标志含义
g全局替换,替换所有匹配
n只替换第 n 个匹配
i忽略大小写
p打印替换的行

替换示例

sed 's/http/https/g' config.txt
sed 's/192.168.1.1/10.0.0.1/g' hosts.txt
sed 's/[0-9]\{4\}/####/g' data.txt

使用不同的分隔符

如果替换内容包含斜杠,可以用其他分隔符:

sed 's#/usr/local#/opt#g' config.txt
sed 's|/home/user|/data/user|g' script.sh

删除操作

d 命令删除行:

sed '3d' file.txt
sed '1,5d' file.txt
sed '$d' file.txt
sed '/pattern/d' file.txt
sed '/^$/d' file.txt

分别表示:删除第3行、删除1到5行、删除最后一行、删除匹配的行、删除空行。

插入和追加

i 在行前插入,a 在行后追加:

sed '1i\第一行' file.txt
sed '$a\最后一行' file.txt
sed '/pattern/i\匹配行之前插入' file.txt
sed '/pattern/a\匹配行之后追加' file.txt

修改行

c 命令替换整行:

sed '1c\新的第一行' file.txt
sed '/error/c\这行被替换了' file.txt

打印行

p 命令打印,通常配合 -n 使用:

sed -n '3p' file.txt
sed -n '1,5p' file.txt
sed -n '/pattern/p' file.txt

直接修改文件

-i 选项直接修改原文件:

sed -i 's/old/new/g' file.txt
sed -i.bak 's/old/new/g' file.txt

第二个命令会先备份原文件为 file.txt.bak,再修改。这是个好习惯,避免改错无法恢复。

多个命令

-e 执行多个命令,或用分号分隔:

sed -e 's/foo/bar/g' -e 's/hello/world/g' file.txt
sed 's/foo/bar/g; s/hello/world/g' file.txt

使用脚本文件

把 sed 命令写入文件,用 -f 选项执行:

cat > replace.sed << 'EOF'
s/error/ERROR/g
s/warning/WARN/g
/^$/d
EOF

sed -f replace.sed app.log

高级用法

使用正则分组

\(\) 分组,用 \1\2 引用:

sed 's/\([a-z]\+\)@\([a-z]\+\)/\2.\1/' file.txt

user@domain 变成 domain.user

扩展正则用 -r,分组用 ()

sed -r 's/([a-z]+)@([a-z]+)/\2.\1/' file.txt

保持空间

sed 有两个缓冲区:模式空间和保持空间。高级操作可以在两个空间之间交换数据:

sed -n '1!G;h;$p' file.txt

这个命令反转文件的所有行。

条件执行

sed '/pattern/!d' file.txt
sed '/start/,/end/d' file.txt

第一个删除不匹配的行,第二个删除从 start 到 end 之间的行。

实用示例

批量修改配置

sed -i 's/debug=false/debug=true/' config.ini
sed -i 's/port=8080/port=9090/' app.conf

删除注释和空行

sed -i '/^#/d;/^$/d' config.conf

提取 IP 地址

sed -r 's/.*([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+).*/\1/' access.log

小结

  • sed 是流编辑器,按行处理文本
  • s/// 替换,d 删除,i 插入,a 追加
  • -i 直接修改文件,建议配合备份使用
  • -r 使用扩展正则表达式
  • 复杂操作可以用脚本文件