跳到主要内容

2、sed

sed

目录

[toc]

简介

sed 是一种新型的,非交互式的编辑器。它能执行与编辑器 vi 和 ex 相同的编辑任务。sed 编辑器没有提供交互式使用方式,使用者只能在命令行输 入编辑命令、指定文件名,然后在屏幕上查看输出。 **sed 编辑器没有破坏性,它不会修改文件,除非使用 shell 重定向来保存输出结果。**默认情况 下,所有的输出行都被打印到屏幕上。

  • sed工作过程

sed 编辑器逐行处理文件(或输入),并将输出结果发送到屏幕。 sed 的命令就是在 vi和 ed/ex 编辑器中见到的那些。 sed 把当前正在处理的行保存在一个临时缓存区中,这个缓存区称为模式空间或临时缓冲。sed 处理完模式空间中的行后(即在该行上执行 sed 命令后),就把改行发送到屏幕上(除非之前有命令删除这一行或取消打印操作)。 sed 每处理完输入文件的最后一行后, sed 便结束运行。 sed 把每一行都存在临时缓存区中,对 这个副本进行编辑,所以不会修改或破坏源文件。

从上图可以看出 sed 不是破坏性的,它不会修改正在编辑的文件。

语法

sed 命令行格式为: 
sed [选项] ‘command’ 输入文本

选项

  • sed 操作命令
a\	在当前行后添加一行或多行
c\ 用新文本修改(替换)当前行中的文本
d 删除行
i\ 在当前行之前插入文本

h 把模式空间里的内容复制到暂存缓存区
H 把模式空间里的内容追加到暂存缓存区

g 取出暂存缓冲区里的内容,将其复制到模式空间,覆盖该处原有内容
G 取出暂存缓冲区里的内容,将其复制到模式空间,追加在原有内容后面

l 列出非打印字符
p 打印行

n 读入下一输入行,并从下一条命令而不是第一条命令开始处理
q 结束或退出 sed
r 从文件中读取输入行
! 对所选行意外的所有行应用命令

s 用一个字符串替换另一个 #常用
n	使用安静模式,在一般情况所有的 STDIN 都会输出到屏幕上,加入-n 后只打印被 sed 特殊处理的行;😉
e 多重编辑,且命令顺序会影响结果;
f 指定一个 sed 脚本文件到命令行执行;
r sed 使用扩展正则;
i 直接修改文档读取的内容,不在屏幕上输出 //一般是直接修改:加参数-i 😉
  • 替换标志
g	在行内进行全局替换 😉
p 打印行 😉
w 将行写入文件
x 交换暂存缓冲区与模式空间的内容
y 将字符转换为另一字符(不能对正则表达式使用 y 命令)

插入:-i

i 命令是插入命令,类似于 a 命令,但不是在当前行后增加文本,而是在当前行前面插入新的文本,即刚读入缓存区模式的行。

  • 选项含义
i\	在当前行之前插入文本

替换

案例:替换

sed -i s/SELINUX=enforcing/SELINUX=disabled/ /etc/selinux/config

删除

案例:删除以某个字段所在的行

#先打印
[root@mysql ~]# sed -n '/^DROP TABLE/p' /backup/inc.sql
DROP TABLE `students` /* generated by server */

#删除
[root@mysql ~]# sed -i.bak '/^DROP TABLE/d' /backup/inc.sql
[root@mysql ~]# ll /backup/inc.sql
-rw-r--r--. 1 root root 2909 Sep 22 17:17 /backup/inc.sql
[root@mysql ~]# ll /backup/inc.sql.bak
-rw-r--r--. 1 root root 2957 Sep 22 17:12 /backup/inc.sql.bak

注释某行

案例:修改 /etc/fstab 文件,注释掉 SWAP 的自动挂载

# 修改 /etc/fstab 文件,注释掉 SWAP 的自动挂载
swapoff -a
sed -ri 's/.*swap.*/#&/' /etc/fstab

# 使用 free -m 确认 swap 已经关闭
[root@master1 ~]#free -mh
total used free shared buff/cache available
Mem: 1.8G 89M 1.5G 9.5M 144M 1.5G
Swap: 0B 0B 0B

说明:

  • -r:启用扩展正则表达式,使得在模式匹配中可以使用更多的功能和语法。
  • .*swap.*:这是一个正则表达式,表示匹配包含单词 swap 的整行。.* 意味着匹配任意字符(包括空字符)零次或多次。
  • #&:这是替换的内容。# 是一个注释符号,& 表示匹配到的整个字符串。因此,整行会被替换为以 # 开头,加上原行内容。

综上所述,这条命令的作用是:

  1. /etc/fstab 文件中查找所有包含单词 swap 的行。
  2. 将这些行的内容替换为原来的内容,并在开头添加一个 #,使其变成注释。

执行后,所有包含 swap 的行将被注释掉,这意味着在系统启动时不会处理这些行。

案例:sed命令给文本文件指定行前插入内容

sed -i '1i\Your Text to Insert' filename

这会在 filename 文件的第一行之前插入指定的文本。请注意,-i 选项表示直接在文件中编辑,如果你不希望修改原始文件,可以省略 -i 选项,然后将输出重定向到一个新文件。

  • 自己测试(测试成功)
[root@hg-linux-test ~]# cat test.txt 
1
2
3
[root@hg-linux-test ~]# sed -i '1i\Your Text to Insert' test.txt
[root@hg-linux-test ~]# cat test.txt
Your Text to Insert
1
2
3
[root@hg-linux-test ~]#

案例:编辑前同时备份文件

#删除
[root@mysql ~]# sed -i.bak '/^DROP TABLE/d' /backup/inc.sql

[root@mysql ~]# ll /backup/inc.sql
-rw-r--r--. 1 root root 2909 Sep 22 17:17 /backup/inc.sql
[root@mysql ~]# ll /backup/inc.sql.bak
-rw-r--r--. 1 root root 2957 Sep 22 17:12 /backup/inc.sql.bak

说明:

  • -i.bak:表示对文件进行原地编辑,并在修改前创建一个备份文件。备份文件的扩展名为 .bak,这意味着如果原始文件是 inc.sql,那么在编辑之前会创建一个 inc.sql.bak 的备份副本。
  • d:表示删除匹配到的行。

案例:sed打印只改变的行

测试成功。

是的,sed(流编辑器)可以通过使用 -n 选项以及 p 命令来实现只打印被修改的行。下面是一个简单的示例:

sed -n 's/pattern/replacement/p' filename

在这个例子中:

  • -n 参数告诉 sed 不要自动打印每一行。
  • s/pattern/replacement/p 表示查找匹配 pattern 的行,用 replacement 替换,然后打印结果。

这样,只有被修改的行才会被打印。请注意,如果某一行没有发生替换,那么它将不会被打印。


选项含义:

  -n, --quiet, --silent
suppress automatic printing of pattern space #`-n` 参数告诉 `sed` 不要自动打印每一行。

测试过程:

例如,假设有一个文件 example.txt 包含以下内容:

[root@hg-linux-test ~]# cat example.txt 
apple
banana
cherry
date
[root@hg-linux-test ~]#
  • 你可以使用以下 sed 命令:
[root@hg-linux-test ~]# sed -n 's/a/X/p' example.txt
Xpple
bXnana
dXte
[root@hg-linux-test ~]#

这将把每一行中的第一个 'a' 替换为 'X',并只打印被修改的行。

  • 如果你想要对文件进行原地修改,你可以使用 -i 选项,但请谨慎使用,因为这将更改源文件:
[root@hg-linux-test ~]# sed -i -n 's/a/X/p' example.txt
[root@hg-linux-test ~]# cat example.txt
Xpple
bXnana
dXte
[root@hg-linux-test ~]#
  • 如果你只是想要查看替换结果而不修改文件,可以使用 cat 命令:
cat example.txt | sed -n 's/a/X/p'   等价于   sed -n 's/a/X/p' example.txt

[root@hg-linux-test ~]# cat example.txt | sed -n 's/a/X/p'
Xpple
bXnana
dXte
[root@hg-linux-test ~]#

这样,原始文件内容将保持不变。

  • 要全部替换内,该如何办?(加上一个g选项就好了)
[root@hg-linux-test ~]# sed -n 's/a/XX/pg' example.txt
XXpple
bXXnXXnXX
dXXte
[root@hg-linux-test ~]#

正则选项:-r

案例

[root@mysql ~]# mysql -uroot -e 'show databases'|grep -Ev '^(Database|information_schema|performance_schema)$' | sed -rn 's#(.*)#mysqldump -B \1 | gzip > /backup/\1.sql.gz#p' |bash
[root@mysql ~]# ll /backup/ -t
total 3092
-rw-r--r--. 1 root root 137110 Sep 23 06:56 mysql.sql.gz
-rw-r--r--. 1 root root 1900 Sep 23 06:56 hellodb2.sql.gz
-rw-r--r--. 1 root root 1971 Sep 23 06:56 hellodb.sql.gz
-rw-r--r--. 1 root root 519 Sep 23 06:56 db2.sql.gz
……

| sed -rn 's#(.*)#mysqldump -B \1 | gzip > /backup/\1.sql.gz#p'

  • 将经过过滤的数据库列表传递给 sed 命令,进行格式化处理。
  • -r 选项启用扩展正则表达式,-n 选项使 sed 只输出被处理的行。
  • s#(.*)#mysqldump -B \1 | gzip > /backup/\1.sql.gz#p
    • s#(.*)#...# 是替换命令,将匹配到的行替换为 mysqldump 命令。
    • \1 表示被匹配的数据库名称。
    • 最终输出的格式是 mysqldump -B 数据库名 | gzip > /backup/数据库名.sql.gz

案例:\s* 匹配零个或多个空白字符(如空格、制表符)

显示系统信息

echo -e "\tCpu          : $(lscpu | grep "Model name:" | sed 's/Model name:\s*//')"




sed 's/Model name:\s*//'

sed 是一个流编辑器,用于对文本进行处理和转换。
这里的 sed 命令执行的是替换操作:

s/Model name:\s*// 是一个替换表达式:
s 表示替换命令。
Model name:\s* 是要匹配的模式。
Model name: 匹配文本 Model name:。

\s* 匹配零个或多个空白字符(如空格、制表符)。
// 表示将匹配的部分替换为空(即删除匹配的部分)。

经过 sed 处理后,上述示例行会变成:
Intel(R) Core(TM) i7-8550U CPU @ 1.80GHz

image-20240729061630078

案例

[root@mysql ~]# mysql -uroot -e 'show databases'|sed -rn '/^(Database|information_schema|performance_schema)$/!s#(.*)#mysqldump -B \1 | gzip > /backup/\1.sql.gz#p' |bash
[root@mysql ~]# ll /backup/ -t
total 3092
-rw-r--r--. 1 root root 137111 Sep 23 06:58 mysql.sql.gz
-rw-r--r--. 1 root root 1900 Sep 23 06:58 hellodb2.sql.gz
-rw-r--r--. 1 root root 1971 Sep 23 06:58 hellodb.sql.gz
-rw-r--r--. 1 root root 519 Sep 23 06:58 db2.sql.gz

image-20240923071622653

总结

本章内容总结了 sed 命令的用法,前面部分是 sed 命令的语法,后面部分则主要以实际案例来说明 sed 的用法,最后面一点介绍了 sed 命令在生产实践中的运用。所谓学为练,练为战,希望大家能够将 sed 命令勤加练习,必将会在工作中有所用途,尤其是**频繁的分析日志文件, Awk+sed 是比 较好的组合。**最后希望本文对大家有所帮助,真正达到熟练的程度这就靠大家在工作中归纳总结了。

关于我

我的博客主旨:

  • 排版美观,语言精炼;
  • 文档即手册,步骤明细,拒绝埋坑,提供源码;
  • 本人实战文档都是亲测成功的,各位小伙伴在实际操作过程中如有什么疑问,可随时联系本人帮您解决问题,让我们一起进步!

🍀 微信二维码

x2675263825 (舍得), qq:2675263825。

image-20230107215114763

🍀 微信公众号

《云原生架构师实战》

image-20230107215126971

🍀 个人主页:

https://onedayxyy.cn

image-20240805214647028

🍀 知识库:

https://wiki.onedayxyy.cn/

🍀 博客:

http://blog.onedayxyy.cn/

image-20240804075845906

🍀 csdn

https://blog.csdn.net/weixin_39246554?spm=1010.2135.3001.5421

image-20230107215149885

🍀 知乎

https://www.zhihu.com/people/foryouone

image-20230107215203185

往期推荐

QQ群

玩转Typora+Docusuaurus+起始页交流群:(欢迎小伙伴一起探讨有趣的IT技术,来完成一些漂亮的项目)

我的开源项目:

项目名称我的文档我的demo作者demo
1、玩转Typorahttps://wiki.onedayxyy.cn/docs/typorahttps://wiki.onedayxyy.cn/docs/typorahttps://typoraio.cn/#
2、玩转Docusaurushttps://wiki.onedayxyy.cn/docs/mogai-docusaurushttps://wiki.onedayxyy.cn/https://www.docusaurus.cn/
3、个人主页home3.0https://wiki.onedayxyy.cn/docs/home3.0https://onedayxyy.cn/https://github.com/hsBUPT/hsBUPT.github.io
4、全网最美博客-ruyu-bloghttps://wiki.onedayxyy.cn/docs/ruyu-blog-install-one-keyhttps://blog.onedayxyy.cn/https://www.kuailemao.xyz/
5、家庭相册filesite-iohttps://wiki.onedayxyy.cn/docs/filesite.io-photot-install-fullhttps://photo.onedayxyy.cn/https://demo.jialuoma.cn/

https://wiki.onedayxyy.cn/docs/OpenSource

image-20240811063938529

  • typora皮肤

https://wiki.onedayxyy.cn/docs/typora

image-20240518165037517

  • 起始页

https://onedayxyy.cn/

image-20240814230557697

  • 知识库

https://wiki.onedayxyy.cn/

  • 博客

https://blog.onedayxyy.cn/

image-20240803162010305

  • 家庭相册

https://photo.onedayxyy.cn/

image-20240923064332963

最后

好了,关于本次就到这里了,感谢大家阅读,最后祝大家生活快乐,每天都过的有意义哦,我们下期见!