Linux之shell文本编辑工具sed

sed概念

  • sed是一个非交互式的文本编辑器,是将一系列的编辑命令应用于一批文本的理想工具,可以对来自文本文件以及标准输入的文本进行编辑。其中,标准输入可以是来自键盘、文件重定向、字符串、变量或者是管道的文本
  • sed命令拥有非交互式和高效的特点,可以为用户节约大量的时间
  • Vim 采用的是交互式文本编辑模式,可以用键盘命令来交互性地插入、删除或替换数据中的文本。但 sed命令不同,它采用的是流编辑模式,最明显的特点是,在 sed 处理数据之前,需要预先提供一组规则,sed 会按照此规则来编辑数据

工作原理

  • 模式空间pattern space:sed在内存开辟模式空间处理文件的每个输入行,最多8192字节

  • 保留空间holding space:sed在内存开辟保留空间保存已经处理过的输入行,最多8192字节

  • 原理sed 的工作流程主要包括读取、执行和显示三个过程:

    • 读取:sed 从输入流(文件、管道、标准输入)中读取一行内容并存储到临时的缓冲区中(又称模式空间,pattern space)。
    • 执行:默认情况下,所有的sed 命令都在模式空间顺序地执行,除非指定了行的地址,否则sed 命令 将会在所有的行上依次执行。
    • 显示发送修改后的内容到输出流。在发送数据后,模式空间将会被清空
    • 重复上述过程,直到将文件中所有数据处理完毕
  • 在这里插入图片描述

  • 注意:默认情况下所有的sed命令都是在模式空间内执行的,因此输入的文件不会发生任何变化,除非是用重定向存储输出

基本语法

格式

[root@server ~]# sed  -参数  '[定址符]' '操作'  文件名
#定址符和操作一般是连用的(在一个单引号中)

参数

参数 说明
-n 安静模式,不输出模式空间中的内容,在一般sed的用法中,所有来自STDIN的数据一般都会被列出到屏幕上,但如果加上-n参数后,则只有经过sed特殊处理的那一行才会被列出来
-i 直接编辑原文件,而不是由屏幕输出,默认不对原文件进行操作
-e 直接在命令行模式上进行sed的动作编辑的分隔动作,或多个子命令之间也可以用分号隔开,如:sed -e ‘command1;command2… filename 或者 sed -e ‘command1’ -e command2’ ……filename
-r 使用扩展正则表达式
-f 直接将sed的动作写在一个文件内,-f filename则可以执行filename内的sed动作
–help 显示帮助
–version 显示版本
-{} 可组合多个命令,以分号隔开

定位符

  • 用于使用数字指定处理的行区间,或者使用正则进行过滤
  • 表示方法
地址定界 作用
1,5 对文件的1-5行内容进行处理
2,$ 对文件的2到最后一行内容进行处理
1,+3 对文件第1行以及以后的3行内容进行处理
1~2 对文件的1,3,5,7,……的行内容进行处理
/正则表达式/ 对任何能够被正则表达式匹配到的行进行处理

操作

标识 说明
S 替换替换指定字符,一般搭配正则表达式
d 删除,删除选定的行。
p 打印,如果同时指定行,表示打印指定行;如果不指定行,则表示打印所有内容;如果有非打印字符,则以 ASCII 码输出。其通常与“-n”选项一起使用。
= 打印行号。
a 增加(append),a 的后面可以接字串,而这些字串会在新的一行出现(目前的下一行)
i 插入(insert),i 的后面可以接字串,而这些字串会在新的一行出现(目前的上一行)
c 行替换,指定行中的所有内容,替换成该选项后面的字符串。
y 字符转换,转换前后的字符长度必须相同。
l 打印数据流中的文本和不可打印的ASCII字符(比如结束符$、制表符\t)
! 指定行以外的所有行
& 代表匹配到的内容

输出文本

范例文本

[root@server ~]# sed -n 'p' sed1.txt #全文打印,-n只有经过处理的才会被打印,p表示打印

[root@server ~]# sed  -n  '=;p'  sed1.txt  # 全文打印并显示行号,分号用来分割动作

[root@server ~]#  sed -n -e '=;p' sed1.txt  #使用-e效果同上

[root@server ~]# sed -n -e '=' -e 'p' sed1.txt #使用-e效果同上

[root@server ~]# sed -n 'l' sed1.txt  #全文显示并输出控制字符(比如结束符$、制表符\t)

[root@server ~]# sed -n '    #全文打印,交互模式
> =
> p
> ' sed1.txt

注:不加-n会重复显示,不加p无法打印,所以-n和p连用使用

定址符和操作符连用

[root@server ~]# sed -n '1p' sed1.txt   #打印第一行

[root@server ~]# sed -n '4,6p' sed1.txt  #打印4-6行

[root@server ~]# sed -n '3,12p' sed1.txt  #打印3-12行,超行范围只显示实际内容

[root@server ~]# sed -n '7,$p' sed1.txt  #打印7到最后一行

[root@server ~]# sed -n '$p' sed1.txt  #打印最后一行

[root@server ~]# sed  -n  '2~2p'  sed1.txt  #打印偶数行

[root@server ~]# sed -n '1~2p' sed1.txt  #打印奇数行

[root@server ~]# sed -n '4p;6p;8p' sed1.txt                #打印4、6、8行
[root@server ~]# sed -n -e '4p' -e '6p' -e '8p' sed1.txt   #打印4、6、8行

[root@server ~]# sed -n '1,+5p' sed1.txt  #打印第1行及其后5行

[root@server ~]# sed -n '1!p' sed1.txt  #打印除了第1行的其他行

[root@server ~]# sed -n '2,3!p' sed1.txt  #打印除了2-3行的剩余行

[root@server ~]# sed -n '1~2!p' sed1.txt  #打印偶数行

搭配正则使用

正则表达式写在//中间

[root@server ~]# sed  -n  '/^f/p'  sed1.txt  # 打印f开头的行

[root@server ~]# sed  -n  '/t/p'  sed1.txt  # 检索包含t的行

[root@server ~]# sed  -n  '/^t/p ; /^f/p'  sed1.txt  # 检索包含t开头或者包含f开头的行信息
[root@server ~]# sed -n -e '/^t/p' -e '/^f/p' sed1.txt  # 检索包含t开头或者包含f开头的行信息

[root@server ~]# sed -n '2,/five/p' sed1.txt  #检索第2行到five所在行

[root@server ~]# sed -n '/n$/p' sed1.txt  #检索n结尾的行信息

规定语法

[root@server ~]# sed  -n  'n;p'  sed1.txt  # 检索偶数行

[root@server ~]# sed  -n  'p;n'  sed1.txt  # 检索奇数行

[root@server ~]# sed  -n  '$='  sed1.txt  # 打印文本的总行数

文本替换

范例文件

/etc/passwd

[root@server ~]# cp  /etc/passwd  ~/ps
[root@server ~]# cat ps
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
nobody:x:65534:65534:Kernel Overflow User:/:/sbin/nologin
systemd-coredump:x:999:997:systemd Core Dumper:/:/sbin/nologin
dbus:x:81:81:System message bus:/:/sbin/nologin
polkitd:x:998:996:User for polkitd:/:/sbin/nologin
avahi:x:70:70:Avahi mDNS/DNS-SD Stack:/var/run/avahi-daemon:/sbin/nologin
tss:x:59:59:Account used for TPM access:/dev/null:/sbin/nologin
colord:x:997:993:User for colord:/var/lib/colord:/sbin/nologin
clevis:x:996:992:Clevis Decryption Framework unprivileged user:/var/cache/clevis:/usr/sbin/nologin
rtkit:x:172:172:RealtimeKit:/proc:/sbin/nologin
sssd:x:995:991:User for sssd:/:/sbin/nologin
geoclue:x:994:990:User for geoclue:/var/lib/geoclue:/sbin/nologin
libstoragemgmt:x:993:989:daemon account for libstoragemgmt:/var/run/lsm:/sbin/nologin
setroubleshoot:x:992:988:SELinux troubleshoot server:/var/lib/setroubleshoot:/sbin/nologin
pipewire:x:991:986:PipeWire System Daemon:/var/run/pipewire:/sbin/nologin
flatpak:x:990:985:User for flatpak system helper:/:/sbin/nologin
gdm:x:42:42::/var/lib/gdm:/sbin/nologin
cockpit-ws:x:989:984:User for cockpit web service:/nonexisting:/sbin/nologin
cockpit-wsinstance:x:988:983:User for cockpit-ws instances:/nonexisting:/sbin/nologin
gnome-initial-setup:x:987:982::/run/gnome-initial-setup/:/sbin/nologin
sshd:x:74:74:Privilege-separated SSH:/usr/share/empty.sshd:/sbin/nologin
chrony:x:986:981::/var/lib/chrony:/sbin/nologin
dnsmasq:x:985:980:Dnsmasq DHCP and DNS server:/var/lib/dnsmasq:/sbin/nologin
tcpdump:x:72:72::/:/sbin/nologin
systemd-oom:x:978:978:systemd Userspace OOM Killer:/:/usr/sbin/nologin
redhat:x:1000:1000::/home/redhat:/bin/bash

格式

[root@server ~]# sed -参数  '行范围s/旧字符串/新字符串/替换标记'  文件名

#注:旧字符串可以是正则表达式
  • 行范围使用数字表示,即对第几行到第几行进行替换处理,若省略则表示进行全文处理
  • s: 表示替换动作
  • 替换标记
    • 数字:使用1-512之间的数字,表示指定需要替换的字符串出现第几次才进行替换
    • g对数据中所有匹配到的内容进行替换,若省略g则只会对第一次匹配的内容进行替换
    • p替换成功立刻打印一般与-n一起使用
    • w 文件名 : 将缓冲区的内容写入到指定文件
    • & : 使用正则表达式匹配的内容进行替换
    • \ :转义符,若有特殊符号或路径则需要转义

示例

[root@server ~]# sed -n 's/root/boot/gp'  ~/ps  #全文替换包含root为boot

[root@server ~]# sed    's/root/boot/g'   ~/ps # 不加-n及动作p会显示未变化的和变化的行信息(所有行)

[root@server ~]# sed -n 's/root/admin/2p'  ~/ps  #将每一行第2次出现的root替换为admin

[root@server ~]# sed -n 's/root/admin/p'  ~/ps  #不加g,默认将每一行第1个root替换为admin

[root@server ~]# sed -n '4s/adm/root/gp'  ~/ps  #将第4行的adm全部替换为root
# 注意:替换的内容及新字符串中有路径分隔符,为了与sed的斜杠分隔符区分开来,需要对路径分隔符/之前增加 转义符\
[root@server ~]# sed  -n  's/\/sbin\/nologin/\/bin\/bash/gp'   ~/ps


# 注意:若替换内容及新内容中有路径/符号,可以将sed自带的三个/更换成#
[root@server ~]# sed  -n  's#/sbin/nologin#/bin/bash#gp'   ~/ps


# 注意:由于上例,则sed自带三个/可以更换成#
[root@server ~]# sed  -n  's#root#boot#gp'  ~/ps


# 注意:若替换内容就是#时,sed自带三个/不能更换为#



# 将最后一行的所有:替换为@
[root@server ~]# sed -n '$s/:/@/gp'  ~/ps

&示例

[root@server ~]# sed -n  's/^/#/p'  ~/ps #全文增加注释


#查找结果中部分内容插入新内容
[root@server ~]# sed -n 's/SSH/&@/p' ~/ps

#正则搭配使用
[root@server ~]# sed -n  's/.edhat/#/gp'  ~/ps

#在SSH左侧插入@
[root@server ~]# sed -n 's/SSH/@&/p' ps  

# 所有的行首及行尾添加@
[root@server ~]# sed  's/^/@/g  ; s/$/@/g'  ~/ps

#文本第一行之前插入空白行
[root@server ~]# sed  '1s/^/\n/'  ~/ps

# 最后一行插如空白行
[root@server ~]# sed  '$s/$/\n/'  ~/ps

\u大写字母

# 全文所有小写字母改为大写字母,\u表示大写字母,不能写[A-Z]
[root@server ~]# sed  's/[a-z]/\u&/g'   ~/ps

\L小写字母

# 全文所有大写字母改为小写字母,\L为小写字母
[root@server ~]# sed  's/[A-Z]/\L&/g'  ~/ps

\b确定单词边界

#单词首字母大写,\b确定单词边界即第一个字母
[root@server ~]# sed  's/\b[a-z]/\u&/g'   ~/ps

配置实例

# 开启或关闭selinux
[root@server ~]# sed -i 's/SELINUX=disabled/SELINUX=enforcing/'   /etc/selinux/config 

或者

[root@server ~]# sed  -i  '22s/disabled/enforcing/'  /etc/selinux/config 
# httpd网页目录替换
[root@server ~]# yum  install  httpd -y

#mobaxterm上传网页数据
[root@server ~]# sed  -i -e '124s/\/var\/www\/html/\/zy/'  -e '129s/\/var\/www/\/zy/'  /etc/httpd/conf/httpd.conf

[root@server ~]# systemctl start httpd
# 浏览器测试
# 修改bind
[root@server ~]# sed  -i -e 's/127.0.0.1/any/p'  -e 's/localhost/any/' /etc/named.conf 
# 支持管道符即输出重定向
[root@server ~]# echo  "china"  |  sed  's/[a-z]/\u&/'
China
[root@server ~]# echo  "china"  |  sed  's/[a-z]/\u&/g'
CHINA
[root@server ~]# echo  "china"  |  sed  's/[a-z]/\u&/g'  >  t1.txt
[root@server ~]# cat  t1.txt 
CHINA

使用替换实现删除

#将全文root删除
[root@server ~]# sed  -n  's/root//gp'  ~/ps  
[root@server ~]# sed  -n  's/root/''/gp'  ~/ps  #本质

#删除全文注释
[root@server ~]# sed  -n 's/^#//p'  /etc/sos/sos.conf 

#删除每一行第一个字符,^.表示第一个字符
[root@server ~]# sed  -n  's/^.//p'  ~/ps  

#删除每行最后一个字符
[root@server ~]# sed  -n  's/.$//p'  ~/ps 

#删除第5-10的所有的数字
[root@server ~]# sed  -n  '5,10s/[0-9]//gp'  ~/ps 

#删除所有特殊字符(除了数字、字母)另存为到文件t1.txt
[root@server ~]# sed  's/[^(a-z)(A-Z)(0-9)]//gw  t1.txt'   ~/ps   #[^]表示取反
[root@server ~]# cat t1.txt

删除文本

  • d操作用于删除文本的特定行,会删除指定的所有内容,则使用该命令必须特别小心,若忘记指定处理行的话会删除所有内容,也不会有任何输出
[root@server ~]# sed -i 'd' ps  #清空ps文本内容
[root@server ~]# cat ps
[root@server ~]#

示例

# 准备示例文件
[root@server ~]# cp  /etc/sos/sos.conf  ~/sos.conf
[root@server ~]# ls
公共  视频  文档  音乐  anaconda-ks.cfg  sed1.txt
模板  图片  下载  桌面  ps               sos.conf
# 删除第1行
[root@server ~]# sed  '1d' sos.conf 

[root@server ~]# line_number=2
[root@server ~]# sed  "${line_number}d"  sos.conf   # 变量作为行号,需要使用双引号

[root@server ~]# sed  '/^$/d' sos.conf   # 删除全文的空白行

[root@server ~]# sed  '/Options/d' sos.conf  # 删除Options的所在行

# 多个删除条件的写法:
[root@server ~]# sed  -e  '/Options/d'  -e  '/options/d'  sos.conf 
[root@server ~]# sed  '/Options/d ; /options/d'  sos.conf 
[root@server ~]# sed  -e '/Options/d' sos.conf | sed '/options/d'  sos.conf 

#删除包含3到包含5的所有行
[root@server ~]# sed  '/3/,/5/d'  sos.conf 

#删除[开头的行,需要转义
[root@server ~]# sed  '/^\[/d'  sos.conf 

#删除注释行,但是为整行删除
[root@server ~]# sed  '/^#/d'  sos.conf 

注意:删除时先不要加-i写回源文件,否则无法恢复

插入文本

  • 使用 a 动作在文本最后追加一行使用 i 动作在指定行前插入一行,两者格式相同

格式

[root@server ~]# sed  '行范围a(或i)\新文本'  文件名

示例

#在hosts文本最后,追加A记录
[root@server ~]# sed -i '$a\192.168.48.130  www.openlab.com'  /etc/hosts
[root@server ~]# cat  /etc/hosts

#在hosts第3行插入A记录
[root@server ~]# sed  -i  '3i\192.168.48.131  www.openlab.com'  /etc/hosts
[root@server ~]# cat  /etc/hosts


[root@server ~]# sed  -i  '/131/i\192.168.48.132  www.openlab.com'  /etc/hosts
[root@server ~]# cat  /etc/hosts

注意

  • sed命令是基于数据流的处理命令,若文件内容为空,无法插入数据
[root@server ~]# touch  t2.txt
[root@server ~]# cat  t2.txt
[root@server ~]# sed  -i  '$a\xiaoming 18 98.5'  t2.txt
[root@server ~]# cat  t2.txt
[root@server ~]# cat  t2.txt
[root@server ~]# sed  -i  '1i\xiaoming 18 98.5'  t2.txt
[root@server ~]# cat  t2.txt

相关推荐

  1. Linuxshell文本搜索工具grep

    2024-03-20 08:44:07       41 阅读
  2. Shellsed

    2024-03-20 08:44:07       49 阅读
  3. shell编辑器 sed

    2024-03-20 08:44:07       41 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-03-20 08:44:07       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-03-20 08:44:07       100 阅读
  3. 在Django里面运行非项目文件

    2024-03-20 08:44:07       82 阅读
  4. Python语言-面向对象

    2024-03-20 08:44:07       91 阅读

热门阅读

  1. 2023.03.20 晨会汇报

    2024-03-20 08:44:07       43 阅读
  2. 数库据设计最佳实践

    2024-03-20 08:44:07       43 阅读
  3. CSS练习

    CSS练习

    2024-03-20 08:44:07      36 阅读
  4. MongoDB聚合运算符:$hour

    2024-03-20 08:44:07       38 阅读
  5. 双向队列(Double-ended Queue)

    2024-03-20 08:44:07       41 阅读
  6. ElementUI+sortablejs实现列表拖拽功能

    2024-03-20 08:44:07       44 阅读
  7. React——关于表单元素

    2024-03-20 08:44:07       50 阅读