Linux 三剑客之 sed 流编辑器

柳三千

文章最后更新时间:2025年01月24日

前言

sed 是 Linux 系统中一个强大的文本处理工具,全称为 Stream EDitor(流编辑器),它可以对文本进行高效的查找、替换、删除、插入等操作,通常用于处理文本文件或管道输出的文本数据。

应用场景


    批量修改配置文件:可以快速地对大量配置文件中的特定参数进行修改,而无需手动逐个编辑。

    日志处理:从日志文件中提取特定信息、删除无用的日志行或对日志内容进行格式化处理等。

    文本数据清洗和转换:在数据处理过程中,对文本数据进行清洗、转换和格式化,例如将数据中的特定字符替换为其他字符,或者删除不需要的字段等。

    脚本编写:在 Shell 脚本中,sed 常用于文本处理和自动化任务,帮助实现各种文本操作和数据处理需求。

    sed 的 -i 选项可以直接修改文件内容,这功能非常有帮助!举例来说,如果你有一个 100 万行的文件,你要在第 100 行加某些文字,此时使用 vim 可能会疯掉!因为文件太大了!那怎办?就利用 sed 啊!透过 sed 直接修改/取代的功能,你甚至不需要使用 vim 去修订!


图片.png



[ldx@VM-20-5-opencloudos ~]$ cat test 
HELLO LINUX!  
Linux is a free unix-type opterating system.  
This is a linux testfile!  
Linux test 
Google
Taobao
Runoob
Tesetfile
Wiki

#在 test 文件的第四行后添加一行,并将结果输出到标准输出,在命令行提示符下输入如下命令:
[ldx@VM-20-5-opencloudos ~]$ sed -e '4a/新添加一行' test 
HELLO LINUX!  
Linux is a free unix-type opterating system.  
This is a linux testfile!  
Linux test 
/新添加一行
Google
Taobao
Runoob
Tesetfile
Wiki

[ldx@VM-20-5-opencloudos ~]$ sed -e '4a\新添加一行' test # a行后插入
HELLO LINUX!  
Linux is a free unix-type opterating system.  
This is a linux testfile!  
Linux test 
新添加一行
Google
Taobao
Runoob
Tesetfile
Wiki

[ldx@VM-20-5-opencloudos ~]$ sed  '4a\新添加一行' test  #不加-e 也可以
HELLO LINUX!  
Linux is a free unix-type opterating system.  
This is a linux testfile!  
Linux test 
新添加一行
Google
Taobao
Runoob
Tesetfile
Wiki

[ldx@VM-20-5-opencloudos ~]$ cat test  #原文件实际没修改
HELLO LINUX!  
Linux is a free unix-type opterating system.  
This is a linux testfile!  
Linux test 
Google
Taobao
Runoob
Tesetfile
Wiki

[ldx@VM-20-5-opencloudos ~]$ sed  '4i\新添加一行' test   # i 行前插入
HELLO LINUX!  
Linux is a free unix-type opterating system.  
This is a linux testfile!  
新添加一行
Linux test 
Google
Taobao
Runoob
Tesetfile
Wiki

#在第二行后(即加在第三行) 加上drink tea? 字样
[ldx@VM-20-5-opencloudos ~]$ nl test 
     1	HELLO LINUX!  
     2	Linux is a free unix-type opterating system.  
     3	This is a linux testfile!  
     4	Linux test 
     5	Google
     6	Taobao
     7	Runoob
     8	Tesetfile
     9	Wiki
       
[ldx@VM-20-5-opencloudos ~]$ sed '2a drink tea!' test 
HELLO LINUX!  
Linux is a free unix-type opterating system.  
drink tea!
This is a linux testfile!  
Linux test 
Google
Taobao
Runoob
Tesetfile
Wiki

[ldx@VM-20-5-opencloudos ~]$ nl test | sed '2a drink tea'
     1	HELLO LINUX!  
     2	Linux is a free unix-type opterating system.  
drink tea
     3	This is a linux testfile!  
     4	Linux test 
     5	Google
     6	Taobao
     7	Runoob
     8	Tesetfile
     9	Wiki
     
 #如果是要在第二行前,命令如下:
 [ldx@VM-20-5-opencloudos ~]$ nl test | sed '2i drink tea'
     1	HELLO LINUX!  
drink tea
     2	Linux is a free unix-type opterating system.  
     3	This is a linux testfile!  
     4	Linux test 
     5	Google
     6	Taobao
     7	Runoob
     8	Tesetfile
     9	Wiki
     
     
#如果是要增加两行以上,在第二行后面加入两行字,例如 Drink tea or ..... 与 drink beer?
#单引号成功       
[ldx@VM-20-5-opencloudos ~]$ nl test | sed '2a Drink tea or ..... \
> drink beer?'
     1	HELLO LINUX!  
     2	Linux is a free unix-type opterating system.  
Drink tea or ..... 
drink beer?
     3	This is a linux testfile!  
     4	Linux test 
     5	Google
     6	Taobao
     7	Runoob
     8	Tesetfile
     9	Wiki

##双引号失败
[ldx@VM-20-5-opencloudos ~]$ nl test | sed "2a Drink tea or ..... \
> drink beer?"
     1	HELLO LINUX!  
     2	Linux is a free unix-type opterating system.  
Drink tea or ..... drink beer?
     3	This is a linux testfile!  
     4	Linux test 
     5	Google
     6	Taobao
     7	Runoob
     8	Tesetfile
     9	Wiki


#将 test 的内容列出并且列印行号,同时,请将第 2~5 行删除!
[ldx@VM-20-5-opencloudos ~]$ nl test 
     1	HELLO LINUX!  
     2	Linux is a free unix-type opterating system.  
     3	This is a linux testfile!  
     4	Linux test 
     5	Google
     6	Taobao
     7	Runoob
     8	Tesetfile
     9	Wiki
       
[ldx@VM-20-5-opencloudos ~]$ nl test | sed '2,5d'
     1	HELLO LINUX!  
     6	Taobao
     7	Runoob
     8	Tesetfile
     9	Wiki
    
#sed 的动作为 2,5d,那个 d 是删除的意思,因为删除了 2-5 行,所以显示的数据就没有 2-5 行了, 另外,原本应该是要下达 sed -e 才对,但没有 -e 也是可以的,同时也要注意的是, sed 后面接的动作,请务必以 '...' 两个单引号括住喔!

#只要删除第 2 行:
[ldx@VM-20-5-opencloudos ~]$ nl test | sed '2d'
     1	HELLO LINUX!  
     3	This is a linux testfile!  
     4	Linux test 
     5	Google
     6	Taobao
     7	Runoob
     8	Tesetfile
     9	Wiki
   
 #要删除第 3 到最后一行:
 [ldx@VM-20-5-opencloudos ~]$ nl test | sed '3,$d'
     1	HELLO LINUX!  
     2	Linux is a free unix-type opterating system.
   
 #删除 test 所有包含 oo 的行,其他行输出
 [ldx@VM-20-5-opencloudos ~]$ nl test
     1	HELLO LINUX!  
     2	Linux is a free unix-type opterating system.  
     3	This is a linux testfile!  
     4	Linux test 
     5	Google
     6	Taobao
     7	Runoob
     8	Tesetfile
     9	Wiki
       
[ldx@VM-20-5-opencloudos ~]$ nl test | sed '/oo/d'
     1	HELLO LINUX!  
     2	Linux is a free unix-type opterating system.  
     3	This is a linux testfile!  
     4	Linux test 
     6	Taobao
     8	Tesetfile
     9	Wiki


#将第 2-5 行的内容取代成为 No 2-5 number 呢?
[ldx@VM-20-5-opencloudos ~]$ nl test
    1 HELLO LINUX!  
    2 Linux is a free unix-type opterating system.  
    3 This is a linux testfile!  
    4 Linux test
    5 Google
    6 Taobao
    7 Runoob
    8 Tesetfile
    9 Wiki
     
[ldx@VM-20-5-opencloudos ~]$ nl test | sed '2,5c No number'   #c 覆盖指定整行的内容
    1 HELLO LINUX!  
No number
    6 Taobao
    7 Runoob
    8 Tesetfile
    9 Wiki

#搜索 testfile,找到 oo 对应的行,执行后面花括号中的一组命令,每个命令之间用分号分隔,这里把 oo 替换为 kk,再输出这行:
[ldx@VM-20-5-opencloudos ~]$ nl test 
     1	HELLO LINUX!  
     2	Linux is a free unix-type opterating system.  
     3	This is a linux testfile!  
     4	Linux test 
     5	Google
     6	Taobao
     7	Runoob
     8	Tesetfile
     9	Wiki
     
     
#s :取代,可以直接进行取代的工作哩!通常这个 s 的动作可以搭配正则表达式!例如 1,20s/old/new/g 就是啦!
#sed -n '/oo/{s/oo/kk/;p;q}':sed 是流编辑器,可对文本进行替换、删除、插入等操作。
#s/oo/kk/:把当前行里的 oo 替换成 kk。
#p:输出替换后的行。
#q:退出 sed 程序,也就是找到第一个包含 oo 的行并处理完后就停止。
#-n:让 sed 不自动输出模式空间的内容,仅在使用 p 命令时才输出。
#/oo/:查找包含 oo 的行。
#{s/oo/kk/;p;q}:这是一组命令,用大括号括起来。

[ldx@VM-20-5-opencloudos ~]$ nl test | sed -n '/oo/{s/oo/kk/;p;q}'
     5	Gkkgle
     
#多点编辑
#一条 sed 命令,删除 testfile 第三行到末尾的数据,并把 HELLO 替换为 RUNOOB :
[ldx@VM-20-5-opencloudos ~]$ nl test
     1	HELLO LINUX!  
     2	Linux is a free unix-type opterating system.  
     3	KK KK KK KKo KK
     4	This is a linux testfile!  
     5	Linux test 
     6	GKKgle
     7	Taobao
     8	RunKKb
     9	Tesetfile
    10	Wiki
       
[ldx@VM-20-5-opencloudos ~]$ nl test | sed -e '3,$d' -e 's/HELLO/RUNOOB/g'
     1	RUNOOB LINUX!  
     2	Linux is a free unix-type opterating system.
#-e 表示多点编辑,第一个编辑命令删除 testfile 第三行到末尾的数据,第二条命令搜索 HELLO 替换为 RUNOOB。


#sed 可以直接修改文件的内容,不必使用管道命令或数据流重导向! 不过,由于这个动作会直接修改到原始的文件,所以请你千万不要随便拿系统配置来测试!
#利用 sed 将 testfile 内每一行结尾若为 . 则换成 !
[ldx@VM-20-5-opencloudos ~]$ nl testfile 
     1	runoob.
     2	google.
     3	taobao.
     4	facebook.
     5	zhihu-
     6	weibo-
[ldx@VM-20-5-opencloudos ~]$ nl testfile  | sed 's/\./!/g'
     1	runoob!
     2	google!
     3	taobao!
     4	facebook!
     5	zhihu-
     6	weibo-
[ldx@VM-20-5-opencloudos ~]$ nl testfile  | sed 's/./!/g'. #没有使用转移字符 \ ,反面教材,请用这样方式确认无误且备份相关文件,再使用 sed -i操作,参考后面习题
!!!!!!!!!!!!!!
!!!!!!!!!!!!!!
!!!!!!!!!!!!!!
!!!!!!!!!!!!!!!!
!!!!!!!!!!!!!
!!!!!!!!!!!!!


#利用 sed 直接在 regular_express.txt 最后一行加入 # This is a test:
[ldx@VM-20-5-opencloudos ~]$ nl testfile 
     1	runoob.
     2	google.
     3	taobao.
     4	facebook.
     5	zhihu-
     6	weibo-
     
[ldx@VM-20-5-opencloudos ~]$ nl testfile | sed '$a This is a test.'
     1	runoob.
     2	google.
     3	taobao.
     4	facebook.
     5	zhihu-
     6	weibo-
This is a test.

[ldx@VM-20-5-opencloudos ~]$ cat testfile # 原文件没变化
runoob.
google.
taobao.
facebook.
zhihu-
weibo-

[ldx@VM-20-5-opencloudos ~]$ sed -i '$a This is a test.' testfile  #确认无误,直接来真的,谨慎操作!
[ldx@VM-20-5-opencloudos ~]$ cat testfile 
runoob.
google.
taobao.
facebook.
zhihu-
weibo-
This is a test.


#搜索 test 有 oo 关键字的行:
[ldx@VM-20-5-opencloudos ~]$ sed '/oo/p' test
HELLO LINUX!  
Linux is a free unix-type opterating system.  
This is a linux testfile!  
Linux test 
Google
Google
Taobao
Runoob
Runoob
Tesetfile
Wiki

[ldx@VM-20-5-opencloudos ~]$ sed -n '/oo/p' test. #-n 只打印经过编辑处理的行
Google
Runoob


数据查找和替换

#选项 i 使 sed 修改文件:
[ldx@VM-20-5-opencloudos ~]$ sed -i '2aoo oo oo ooo oo' test. #新增一行,直接对原文件生效,慎重操作
[ldx@VM-20-5-opencloudos ~]$ nl test
     1	HELLO LINUX!  
     2	Linux is a free unix-type opterating system.  
     3	oo oo oo ooo oo
     4	This is a linux testfile!  
     5	Linux test 
     6	Google
     7	Taobao
     8	Runoob
     9	Tesetfile
    10	Wiki
    
    
#sed 's/要被取代的字串/新的字串/g'
#将 test 文件中每行 第一次 出现的 oo 用字符串 KK 替换,然后将该文件内容输出到标准输出:sed -e 's/oo/kk/' test
       
[ldx@VM-20-5-opencloudos ~]$ nl test | sed 's/oo/KK/'
     1	HELLO LINUX!  
     2	Linux is a free unix-type opterating system.  
     3	KK oo oo ooo oo
     4	This is a linux testfile!  
     5	Linux test 
     6	GKKgle
     7	Taobao
     8	RunKKb
     9	Tesetfile
    10	Wiki

    
# g 标识符表示全局查找替换,使 sed 对文件中所有符合的字符串都被替换,修改后内容会到标准输出,不会修改原文件:
       
[ldx@VM-20-5-opencloudos ~]$ nl test | sed 's/oo/KK/g'   #重点看第三行,跟上面案例对比
     1	HELLO LINUX!  
     2	Linux is a free unix-type opterating system.  
     3	KK KK KK KKo KK
     4	This is a linux testfile!  
     5	Linux test 
     6	GKKgle
     7	Taobao
     8	RunKKb
     9	Tesetfile
    10	Wiki
#批量操作当前目录下以 test 开头的文件:
[ldx@VM-20-5-opencloudos ~]$ echo 'oo aooa aoooa ooaoa' >test2
[ldx@VM-20-5-opencloudos ~]$ ls
1a.txt  1.txt  2.txt  3.txt  4.txt  5.txt  ABC.txt  ab.txt  alss  remoce.txt  test  test2  x.txt
[ldx@VM-20-5-opencloudos ~]$ nl test2
     1oo aooa aoooa ooaoa
[ldx@VM-20-5-opencloudos ~]$ nl test
     1HELLO LINUX!  
     2Linux is a free unix-type opterating system.  
     3oo oo oo ooo oo
     4This is a linux testfile!  
     5Linux test 
     6Google
     7Taobao
     8Runoob
     9Tesetfile
    10Wiki
       
[ldx@VM-20-5-opencloudos ~]$ sed -i 's/oo/KK/g' test*
[ldx@VM-20-5-opencloudos ~]$ cat test
HELLO LINUX!  
Linux is a free unix-type opterating system.  
KK KK KK KKo KK
This is a linux testfile!  
Linux test 
GKKgle
Taobao
RunKKb
Tesetfile
Wiki
[ldx@VM-20-5-opencloudos ~]$ cat test2
KK aKKa aKKoa KKaoa

#获取本机 IP 地址,纯 IP
[ldx@VM-20-5-opencloudos ~]$ ip add
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host noprefixroute 
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether 52:54:00:fd:e4:45 brd ff:ff:ff:ff:ff:ff
    altname enp0s5
    altname ens5
    inet 10.0.20.5/22 brd 10.0.23.255 scope global noprefixroute eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::8b66:86fb:65bc:4fc6/64 scope link noprefixroute 
       valid_lft forever preferred_lft forever
       
[ldx@VM-20-5-opencloudos ~]$ ip add | grep 'inet '
    inet 127.0.0.1/8 scope host lo
    inet 10.0.20.5/22 brd 10.0.23.255 scope global noprefixroute eth0
    
[ldx@VM-20-5-opencloudos ~]$ ip add | grep 'inet ' | grep -v '127'
    inet 10.0.20.5/22 brd 10.0.23.255 scope global noprefixroute eth0
    
[ldx@VM-20-5-opencloudos ~]$ ip add | grep 'inet ' | grep -v '127' | sed 's/inet*//g'

     10.0.20.5/22 brd 10.0.23.255 scope global noprefixroute eth0
[ldx@VM-20-5-opencloudos ~]$ ip add | grep 'inet ' | grep -v '127' | sed 's/inet*//g' | sed 's/\/.*$//g'
     10.0.20.5


文章版权声明:除非注明,否则均为柳三千运维录原创文章,转载或复制请以超链接形式并注明出处。

目录[+]

取消
微信二维码
微信二维码
支付宝二维码