十八、sed 命令修改文件某些关键字段
1、sed 流编辑器
根据事先设计好的一组规则编辑数据流。sed编辑器根据命令来处理数据流中的数据,这些命令要么从命令行中输入,要么存储在一个命令文本文件中。
sed 编辑器没有破坏性,它不会修改文件。默认情况下,所有的输出行都被打印到屏幕上。
sed 的全称是 Stream Editor(流编辑器),它的本意是:
- “读取输入 → 按规则转换 → 输出结果”
- 而不是“直接修改文件”。
这种设计有三大优势:
| 优势 | 说明 |
|---|---|
| 🔹 安全 | 原文件始终不变,避免误操作导致数据丢失 |
| 🔹 灵活 | 输出可重定向、管道传递、组合其他命令 |
| 🔹 符合 Unix 哲学 | “做一件事,并做好”:sed 只负责转换文本流 |
sed是行编辑器,使用者只能在命令行输入编辑命令、指定文件名,然后在屏幕上查看输出。会执行下列操作。
- 一次从输入中读取一行数据。
- 根据所提供的编辑器命令匹配数据。
- 按照命令修改流中的数据。
- 在流编辑器将所有命令与一行数据匹配完毕后,它会读取下一行数据并重复这个过程。
-
sed 把当前正在处理的行保存在一个临时缓存区中,这个缓存区称为模式空间或临时缓冲。sed 处理完模式空间中的行后(即在该行上执行 sed 命令后),就把改行发送到屏幕上(除非之前有命令删除这一行或取消打印操作)。
-
sed 处理完输入文件的最后一行后,sed 便结束运行。sed 把每一行都存在临时缓存区中,对这个副本进行编辑,所以不会修改或破坏源文件。
-
在流编辑器处理完流中的所有数据行后,它就会终止。
- 将新的数据输出到STDOUT 。

命令格式:
sed [选项] ‘command’ 输入文本名
- 选项(Options):控制 sed 行为(如
-n,-i,-E) - 命令(Commands):对文本的操作(如
p,d,s///)命令格式:[地址]命令 或 地址{命令1; 命令2; ...}- “命令”(command) :是对文本执行的操作(如
p、d、s), - “地址”(address) :是指定这些命令作用于哪些行(可以用行号、正则表达式或范围表示)。如果省略地址,命令作用于所有行
- [数字地址 或 /正则地址/]![可选]{命令}
常用选项
选项 说明
-n 使用安静模式,关闭 sed 默认的“自动打印”行为。sed 默认会自动打印每一行。
-e 指定多个命令,命令之间用分号 ; 隔开,在命令末尾和分号之间没有空格。
-f 指定一个 sed 脚本文件到命令行执行,
-r Sed 使用扩展正则
-i 直接修改文档读取的内容,不在屏幕上输出(修改原文件)
-i.bak 修改文档读取的内容,同时创建 .bak的备份文件(先备份原文件内容,再修改原文件)
! 取反,紧跟在地址后面,表示“不匹配该地址的行”。
// sed 操作命令告诉 sed 如何处理由地址指定的各输入行。如果没有指定地址,sed 就会处理输入的所有的行。
命令 说明
a\ 在当前行后添加一行或多行
c\ 用新文本修改(替换)当前行中的文本
d 删除行
i\ 在当前行之前插入文本
h 把模式空间里的内容复制到暂存缓存区
H 把模式空间里的内容追加到暂存缓存区
g 取出暂存缓冲区里的内容,将其复制到模式空间,覆盖该处原有内容
G 取出暂存缓冲区里的内容,将其复制到模式空间,追加在原有内容后面
l 列出非打印字符
p 打印行
n 读取下一输入行,遇到 n 时,自动跳入下一行
q 结束或退出 sed
r 从文件中读取输入行
! 对所选行意外的所有行应用命令
s 用一个字符串替换另一个,语法:s/匹配模式/替换内容/[标志]
| 命令 | 说明 | 示例 |
|---|---|---|
p |
打印当前行 | 5p → 打印第5行 |
d |
删除当前行 | /^$/d → 删除空行 |
s/old/new/ |
替换 | s/foo/bar/g → 全局替换 foo 为 bar |
= |
打印行号 | 5= → 打印 5(单独一行) |
q |
退出 sed | 10q → 处理到第10行后退出 |
w file |
写入文件 | /error/w err.log → 匹配行写入 err.log |
sed 定位特定的行来处理,指定要处理的行
1、数字定址(不用 //)
直接写行号或 $(最后一行):
5d # 删除第5行
$d # 删除最后一行
10p # 打印第10行(需 -n)
地址符号
| 符号 | 含义 | 示例 |
|---|---|---|
$ |
最后一行 | sed '$d' file → 删除最后一行 |
0 |
仅用于特殊范围(如 0,/pattern/) |
sed '0,/foo/d' file → 删除从开头到第一个含 foo 的行(包括该行) |
~ |
步长(GNU sed) | sed '1~2d' file → 删除奇数行(1,3,5...) |
+N |
相对偏移(GNU sed) | /error/,+2p → 匹配行 + 后2行 |
2、正则定址(必须用 //)
当地址是“匹配某内容的行”时,用 /正则/:
格式:
/开始模式/,/结束模式/
^ // 匹配行开始,如:/^sed/匹配所有以sed开头的行。 $ // 匹配行结束,如:/sed$/匹配所有以sed结尾的行。 . // 匹配一个非换行符的任意字符,如:/s.d/匹配s后接一个任意字符,最后是d。 * // 匹配0个或多个字符,如:/*sed/匹配所有模板是一个或多个空格后紧跟sed的行。 [] //匹配一个指定范围内的字符,如/[sS]ed/匹配sed和Sedsed元字符集本文档使用 书栈网 · BookStack.CN 构建 [^] // 匹配一个不在指定范围内的字符,如:/[^A-RT-Z]ed/匹配不包含A-R和T-Z的一个跟ed的行。 \(..\) // 匹配子串,保存匹配的字符,如s/\(love\)able/\1rs,loveable被替换成l & //保存搜索字符用来替换其他字符,如s/love/ **&** /,love这成 **love** 。 \< //匹配单词的开始,如:/\<love/匹配包含以love开头的单词的行。 \> // 匹配单词的结束,如/love\>/匹配包含以love结尾的单词的行。 x\{m\} //重复字符x,m次,如:/0\{5\}/匹配包含5个0的行。 x\{m,\} //重复字符x,至少m次,如:/0\{5,\}/匹配至少有5个0的行。 x\{m,n\} //重复字符x,至少m次,不多于n次,如:/0\{5,10\}/匹配5~10个0的行sed 功能强大的流式文本编
^$ ^表示行头(行首,第一个字符之前)表示行尾(一行最后一个字符之后)^$合在一起,表示空行!!
/error/d # 删除包含 "error" 的行 /^#/d # 删除以 # 开头的行 /[0-9]/p # 打印包含数字的行(需 -n)
| 地址写法 | 含义 |
|---|---|
5,10d |
删除第5到第10行(数字范围,无 //) |
/start/,/end/d |
删除从含 "start" 到含 "end" 的行(正则范围,用 //) |
1,/quit/d |
从第1行到首次出现 "quit" 的行(混合) |
3)取反 ! 的写法
! 紧跟在地址后面,表示“不匹配该地址的行”:
1!d # 除第1行外,全部删除 /error/!d # 删除不包含 "error" 的行 10,20!s/a/A/g # 在10~20行之外,替换 a → A
4)当要在某个地址范围内执行多个命令:
地址{命令1;命令2;} 1,3{/123/d} # 在1~3行中,删含123的行 /error/{s/foo/bar/;p} # 对含 error 的行:替换并打印(需 -n)
5)s 命令的 flags 详解
语法:
s/匹配模式/替换内容/[flags]
常用 flags 列表:
| Flag | 含义 | 示例 | 说明 |
|---|---|---|---|
| (无) | 替换每行第一个匹配 | s/foo/bar/ |
默认行为 |
g |
全局替换(每行所有匹配) | s/foo/bar/g |
最常用 |
数字 N |
替换每行中第 N 个匹配 | s/a/A/2 |
只替换第二个 a |
p |
打印被替换的行(需配合 -n) |
sed -n 's/error/ERROR/p' |
类似 grep 效果 |
w 文件名 |
将成功替换的行写入文件 | s/foo/bar/w changed.txt |
注意:是写入整行 |
i |
忽略大小写匹配(GNU sed) | s/HTTP/http/gi |
匹配 http、HTTP、Http 等 |
I |
同 i(某些实现) |
s/GET/get/I |
兼容性略差,推荐用 i |
echo "foo foo foo" | sed 's/foo/bar/' // 输出:bar foo foo ← 只换第一个 echo "foo foo foo" | sed 's/foo/bar/g' // 输出:bar bar bar ← 全部替换 echo "a a a a" | sed 's/a/A/3' // 输出:a a A a ← 只换第3个 a
例子:
// 打印第2~5行 sed -n '2,5p' file.txt // 打印包含 "error" 的行 sed -n '/error/p' file.txt // 删除第1行 sed '1d' file.txt // 删除注释行(以#开头) sed '/^#/d' file.txt // 删除1~3行中包含 "test" 的行 sed '1,3{/test/d}' file.txt // 替换每行第一个 "old" → "new" sed 's/old/new/' file.txt // 全局替换所有 "old" → "new" sed 's/old/new/g' file.txt // 替换每行第2个 "a" → "A" sed 's/a/A/2' file.txt // 替换并打印被修改的行(需 -n) sed -n 's/error/ERROR/gp' file.txt // 将行首数字加括号:5 → (5) sed 's/^[0-9]/(&)/' file.txt // 使用分组引用:abc123 → 123-abc sed 's/\([a-z]*\)\([0-9]*\)/\2-\1/' file.txt // 在第2行后追加一行 sed '2a\New line here' file.txt // 在匹配行前插入 sed '/ERROR/i\--- WARNING ---' log.txt // 替换整行(将含 "temp" 的行替换为 "REMOVED") sed '/temp/c\REMOVED' file.txt // 删除**不包含** "success" 的行(只保留 success 行) sed '/success/!d' file.txt // 除第1行外,全部替换 "foo" → "bar" sed '1!s/foo/bar/g' file.txt //多命令组合 // 方法1:用 ; 分隔 sed 's/foo/bar/g; /^$/d' file.txt // 方法2:用 {} 命令组 sed '/DEBUG/{s/old/new/g; p}' file.txt // 方法3:用 -e sed -e 's/a/A/g' -e 's/b/B/g' file.txt
本文来自博客园,作者:chao_xiong,转载请注明原文链接:https://www.cnblogs.com/chao-xiong/p/16195530.html

浙公网安备 33010602011771号