十八、sed 命令修改文件某些关键字段

1、sed 流编辑器

根据事先设计好的一组规则编辑数据流。sed编辑器根据命令来处理数据流中的数据,这些命令要么从命令行中输入,要么存储在一个命令文本文件中。

sed 编辑器没有破坏性,它不会修改文件。默认情况下,所有的输出行都被打印到屏幕上。

sed 的全称是 Stream Editor(流编辑器),它的本意是:

  • “读取输入 → 按规则转换 → 输出结果”
  • 而不是“直接修改文件”。

这种设计有三大优势:

优势说明
🔹 安全 原文件始终不变,避免误操作导致数据丢失
🔹 灵活 输出可重定向、管道传递、组合其他命令
🔹 符合 Unix 哲学 “做一件事,并做好”:sed 只负责转换文本流

sed是行编辑器,使用者只能在命令行输入编辑命令、指定文件名,然后在屏幕上查看输出。会执行下列操作。

  1. 一次从输入中读取一行数据。
  2. 根据所提供的编辑器命令匹配数据。
  3. 按照命令修改流中的数据。
    • 在流编辑器将所有命令与一行数据匹配完毕后,它会读取下一行数据并重复这个过程。
    • sed 把当前正在处理的行保存在一个临时缓存区中,这个缓存区称为模式空间或临时缓冲。sed 处理完模式空间中的行后(即在该行上执行 sed 命令后),就把改行发送到屏幕上(除非之前有命令删除这一行或取消打印操作)。

    • sed 处理完输入文件的最后一行后,sed 便结束运行。sed 把每一行都存在临时缓存区中,对这个副本进行编辑,所以不会修改或破坏源文件。

    • 在流编辑器处理完流中的所有数据行后,它就会终止。

  4. 将新的数据输出到STDOUT 。

命令格式:

sed [选项] ‘command’ 输入文本名
  • 选项(Options):控制 sed 行为(如 -n-i-E
  • 命令(Commands):对文本的操作(如 pds///
    • 命令格式:[地址]命令 或  地址{命令1; 命令2; ...}
    • 命令”(command) :是对文本执行的操作(如 pds),
    • “地址”(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 匹配 httpHTTPHttp 等
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

 

posted @ 2025-11-17 15:42  chao_xiong  阅读(23)  评论(0)    收藏  举报