sed - 文本三剑客之编辑功能

本文深入解析SED流编辑器的功能与用法,包括基本文本转换、正则表达式匹配及常见编辑命令。通过实例演示如何高效处理文本,实现自动化编辑任务。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

sed - stream editor for filtering and transforming text

Sed是一个流编辑器。流编辑器用于对输入流(文件或管道输入)执行基本的文本转换。虽然在某些方面类似于允许脚本编辑的编辑器(如ed),但sed的工作方式是只对输入进行一次传递,因此效率更高。但是sed能够过滤管道中的文本,这一点与其他类型的编辑器有很大的区别。

一次处理一行内容,在处理时,把当前处理的行存储在临时缓冲区中当中,该缓冲区称为模式空间(Pattern space),接着用sed命令处理缓冲区中的内容,处理完毕后,把缓冲区的内容送到标准输出;然后紧接着去处理下一行,重复完成相同的操作,直至文件未尾;sed处理的整个过程中,对象文件中的内容并没有改变,除非使用重定向来存储处理后的结果,sed主要用来自动编辑一个或多个文件,简化对文件的反复操作过程。默认不编辑原文件,仅对模式空间中的数据进行处理



格式:
sed [option] ... '[address-range][script]' inputfile...

常用选项:

  • -n:不输出模式中的内容至屏幕
  • -e:多点编辑
  • -r:支持扩展正则表达式
  • -f /path/to/sript_file:从指定文件中读取编辑脚本
  • -i:原处编辑



地址定界(address-range):

  1. 不给定地址,默认将对全文进行处理
  2. 单地址:
    • #:指定的行
    • /pattern/:被此模式匹配的每一行
    • $:最后一行,$-1就是倒数第二行
  3. 地址范围:
    • #,#:1,3第一行到第三行
    • #,+#:1,+2第一行到1+2=3行
    • /pattern1/,/pattern2/:从第一个匹配到pattern1到第一个匹配pattern2的中间所有行
    • #,/pattern/:从第多少行到第一个匹配pattern的行中间所有行

pattern支持正则表达式方法。



编辑命令:

  • d:删除
  • p:显示模式空间的内容
  • c \test:将选定的行替换为文本
  • a \test:在行后面追加文本,支持使用\n实现多行追加
  • i \test:在行前面追加文本,支持使用\n实现多行追加
  • r /path/to/somefile:读取指定文件的文本流至模式空间中匹配的行的行后
  • w /path/to/somefile:保存模式空间匹配到的行至指定文件中
  • =:为模式空间中行打印行号
  • !:取反条件,写于位置后
  • s/// s@pattern@replace@ s### //如果pattern和replace中有的字符与分隔符(s后的和一个字符)相同,即可用\转义,也可将修改成不同的分隔符(如!@#$%^&*),这样阅读起来方便些,避免不必要的错误。
    替换标记:
    - g:行内全局替换s@@@g。不加g默认只替换每行中第一次被匹配到的串
    - i:忽略字符大小写s@@@i

注:这里的a,c,i,r,w参数都是另起一行追加,并不是在原有行首或行尾追加。



示例:

[root@node1 tmp]# echo first | sed '1p'  #sed默认是将模式空间的内容输出至屏幕,同时又用p选项输出,所以就会输出两次
first
first
[root@node1 tmp]# echo first | sed -n '1p'  #使用-n选项就只输出想要的行,而不是把模式空间中的内容输出
first

[root@node1 tmp]# echo -e "222\n222"| sed  's/2/1/'  #懒惰
122
122
[root@node1 tmp]# echo -e "222\n222"| sed  's/2/1/g' #如果编辑命令后不加g,默认只修改每一行中第一个匹配的值,加上g则表示全局修改(勤奋)
111
111


[root@node1 tmp]# cat a.sh
1
end1
2
end2
3
end3
4
end4
[root@node1 tmp]# sed -n '/1/,/end/p' a.sh
1
end1
[root@node1 tmp]# sed -n '1,/end/p' a.sh  #位置匹配是懒惰的,只匹配第一次匹配到的位置               
1
end1

[root@node1 tmp]# echo -e "222"| sed  's/2/[&]/g'    #可以使用&符号代替匹配到的内容,然后在其前后增加中括号 
[2][2][2]

[root@node1 tmp]# echo -e "222"| sed -e  's/2/1/g' -e 's/1/3/'  #多个匹配
311

sed通常用单引号来引用;也可使用双引号,使用双引号后,双引号会对表达式求值:

$ name=walter
$ echo 'my name is $name' | sed "s@\$name@$name@"
my name is walter



1.删除grub的启动项文件中所有以空白开头的行行首的空白字符

sed 's/^[[:space:]]*//' /etc/grub2.cfg
sed 's/[[:space:]]\+//' /etc/grub2.cfg

2.echo一个绝对路径给sed命令,取出其基名,取出其目录名。

echo /etc/sysconfig/network-scripts/ | sed -r 's@(/.*/)[^/]+/?@\1@'  目录名
echo /etc/sysconfig/network-scripts/ | sed -r 's@/.*/([^/]+)/?@\1@'  基名

3.删除某一行

sed -i '/xxx/d' a.sh

4.注释10-20

sed -i '10,20s@^@#@g' xxx.sh

关键知识:
圆括号括起来的正则表达式所匹配的字符串会可以当成变量来使用,使用方式\1,\2..,按照括号从左到右的顺序给定变量名称

[root@node1 tmp]# echo -e "121"| sed -r 's@(12)@\13@g'   #在匹配的后面加值
1231
[root@node1 tmp]# echo -e "121"| sed -r 's@1(12)@\13@g'  #这个是匹配失败,返回原来的值,匹配不到112
121

[root@node1 tmp]# echo  "1*2 2*1" | sed  -r  's@(\w*\w)\s?(\w\*\w)@\1=\2@'  #\1是1*2,\2是2*1
1*2=2*1

$ echo 'this is en example' | sed -E 's@(\w+)@[\1]@g'
[this] [is] [en] [example]



总结:
sed命令按行编辑,拥有pattern space和hold space两种模式空间,日常所用也就pattern space,但是hold space个人觉得就像是汉诺塔一样有第三个柱子,就多出了很多种玩法了。pattern space就相当于只有两个柱子,玩法自然就少了。vim文本编辑器里的替换功能和sed命令语法一致。所以需要熟练掌握。



hold space高级玩法资料:
https://www.cnblogs.com/fhefh/archive/2011/11/22/2259097.html

转载于:https://www.cnblogs.com/dance-walter/p/10338256.html

### 关于 Sed 的使用教程 Sed(Stream Editor)是一个功能强大的流编辑器,广泛应用于 Linux 和 Unix 系统中。它可以高效地完成多种文本处理任务,例如查找、替换、删除以及格式化文本等操作[^1]。 #### 基本语法结构 Sed 的基本语法如下所示: ```bash sed [选项] '地址范围 操作命令' 文件名 ``` - **选项**:常用的选项包括 `-n` 表示只打印经过 `p` 命令处理的内容;`-e` 可以指定多条命令;`-f` 从脚本文件加载命令;`-i` 实现原地修改文件内容。 - **地址范围**:可以是具体的行号或者通过正则表达式匹配的模式。 - **操作命令**:常见的有替换 (`s`)、删除 (`d`)、插入 (`i`) 和追加 (`a`) 等。 --- #### 替换操作 (s 命令) `s` 命令是最常使用的命令之一,用于将特定文本替换为其他文本。其通用形式为: ```bash sed 's/pattern/replacement/flags' ``` - `pattern`: 被替换的目标字符串或正则表达式。 - `replacement`: 新的替代字符串。 - `flags`: 控制行为的标志位,比如 `g` 表示全局替换,`i` 忽略大小写。 ##### 示例代码 假设有一个名为 `example.txt` 的文件,内容如下: ``` hello world error found here another error line ``` 以下是几个典型的替换例子: ```bash # 将所有的 "error" 替换为 "warning" sed 's/error/warning/g' example.txt # 输出结果: # hello world # warning found here # another warning line ``` 如果只想替换每行的第一个匹配项,则省略 `/g` 参数: ```bash sed 's/error/warning/' example.txt # 输出结果: # hello world # warning found here # another error line ``` 还可以利用反向引用捕获分组并重新排列它们: ```bash echo "John Smith" | sed 's/\(.*\), \(.*\)/\2 \1/' # 输入:"Smith, John" # 输出:"John Smith" ``` --- #### 删除操作 (d 命令) `d` 命令用于删除满足条件的行。例如,删除包含某个关键字的所有行: ```bash sed '/pattern/d' 文件名 ``` ##### 示例代码 继续以上述 `example.txt` 文件为例: ```bash # 删除包含 "error" 的所有行 sed '/error/d' example.txt # 输出结果: # hello world ``` 也可以按照行号来删除某一行或多行: ```bash sed '2d' example.txt # 删除第 2 行 sed '2,3d' example.txt # 删除第 2 到第 3 行 ``` --- #### 插入与附加操作 (i/a 命令) - `i` 命令在指定位置之前插入新行。 - `a` 命令在指定位置之后附加新行。 ##### 示例代码 ```bash # 在第二行前插入一条消息 sed '2i This is an inserted line.' example.txt # 输出结果: # hello world # This is an inserted line. # error found here # another error line ``` 对于追加操作: ```bash sed '2a Appended after the second line.' example.txt # 输出结果: # hello world # error found here # Appended after the second line. # another error line ``` --- #### 组合多个命令 可以通过分号 `;` 连接多个命令,在单次调用中完成复杂任务。例如: ```bash sed -e 's/error/warning/g' -e '$ a End of file message' example.txt ``` 上述命令先将所有 `error` 替换为 `warning`,再在最后一行后面追加一段文字。 --- #### 原地编辑 (-i 选项) 当希望直接修改源文件而非仅显示改动时,可启用 `-i` 参数。例如: ```bash sed -i 's/error/warning/g' example.txt ``` 这会永久保存对 `example.txt` 的更改。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值