Shell编程--sed

发布时间:2024年01月15日

  • sed:stream editor(流编辑器)的缩写是一种在线非交互式编辑器,它一次处理一行内容。处理时,把当前处理的行存储在临时缓冲区中,称为“模式空间”(pattern space),接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。接着处理下一行,这样不断重复,直到文件末尾。

  • Sed主要用来自动编辑一个或多个文件;简化对文件的反复操作;编写转换程序等

  • 非交互式编辑器,一次处理一行内容。

  • 支持正则表达式:与grep一样,sed在文件中查找模式时也可以使用正则表达式(RE)和各种元字符,用于查找和替换,以下是sed支持的元字符:

    • 使用基本元字符集 ^ $ . * [ ] [ ^ ] < > ()
    • 使用扩展元字符集 ? + {x,m} | ( )

1.打印

sed 默认会输出文件的每一行,无论这行的内容是否能匹配上匹配模式,参数p假如被匹配到的则会再输出一次

[root@localhost ~]# sed -r '' /etc/resolv.conf
# Generated by NetworkManager
search localdomain
nameserver 192.168.221.2

//p 是 sed 的内部命令,是 打印(输出) 的作用       
[root@localhost ~]# sed -r 'p' /etc/resolv.conf
# Generated by NetworkManager
# Generated by NetworkManager
search localdomain
search localdomain
nameserver 192.168.221.2
nameserver 192.168.221.2

2.搜索替换

sed会自动打印文件的每一行,同时查找模式匹配的行,找到后执行后面的命令,默认是 p 打印(不加 -n 的情况下)
示例文件:

[root@localhost ~]# vim test.txt
MA Daggett, 341 King Road, Plymouth MA
Alice Ford, 22 East Broadway, Richmond VA
MA Thomas, 11345 Oak Bridge Road, Tulsa OK
Terry Kalkas, 402 Ma Road, mA Falls PA
Eric Adams, 20 Post Road, Sudbury mA
Hubert Sims, 328A Brook Road, Roanoke VA
Amy Wilde, 334 Ma Pkwy, Mountain View CA
Sal Carpenter, 73 MA Street, Boston MA

常用案例:

[root@localhost ~]# sed -r 's/SELINUX=enforcing/SELINUX=disabled/' /etc/sysconfig/selinux
[root@localhost ~]# sed -ri 's/SELINUX=enforcing/SELINUX=disabled/' /etc/sysconfig/selinux
// -r 打印查看,文件内容没有修改;-ri 文件内容被修改

2.1 搜索每一行匹配到MA的将第一个替换为ma

[root@localhost ~]# sed -r 's/MA/ma/' test.txt
ma Daggett, 341 King Road, Plymouth MA
Alice Ford, 22 East Broadway, Richmond VA
ma Thomas, 11345 Oak Bridge Road, Tulsa OK
Terry Kalkas, 402 Ma Road, mA Falls PA
Eric Adams, 20 Post Road, Sudbury mA
Hubert Sims, 328A Brook Road, Roanoke VA
Amy Wilde, 334 Ma Pkwy, Mountain View CA
Sal Carpenter, 73 ma Street, Boston MA

2.2 搜索每一行,找到所有的MA字符,进行全局替换为ma

[root@localhost ~]# sed -r 's/MA/ma/g' test.txt
ma Daggett, 341 King Road, Plymouth ma
Alice Ford, 22 East Broadway, Richmond VA
ma Thomas, 11345 Oak Bridge Road, Tulsa OK
Terry Kalkas, 402 Ma Road, mA Falls PA
Eric Adams, 20 Post Road, Sudbury mA
Hubert Sims, 328A Brook Road, Roanoke VA
Amy Wilde, 334 Ma Pkwy, Mountain View CA
Sal Carpenter, 73 ma Street, Boston ma

2.3 搜索每一行,找到所有的MA字符,进行全局替换为ma,同时忽略大小写

[root@localhost ~]# sed -r 's/MA/ma/gi' test.txt
ma Daggett, 341 King Road, Plymouth ma
Alice Ford, 22 East Broadway, Richmond VA
ma Thomas, 11345 Oak Bridge Road, Tulsa OK
Terry Kalkas, 402 ma Road, ma Falls PA
Eric Adams, 20 Post Road, Sudbury ma
Hubert Sims, 328A Brook Road, Roanoke VA
Amy Wilde, 334 ma Pkwy, Mountain View CA
Sal Carpenter, 73 ma Street, Boston ma

2.4 -n 静默输出(不打印默认输出)

[root@localhost ~]# sed -rn 's/MA/ma/' test.txt

3.多重编辑

3.1 使用多重指令:-e

给予sed多个命令的时候需要-e选项;指定多个匹配时,使用-e

[root@localhost ~]# sed -r -e 's/MA/ma/gi' -e 's/PA/pa/gi' test.txt
ma Daggett, 341 King Road, Plymouth ma
Alice Ford, 22 East Broadway, Richmond VA
ma Thomas, 11345 Oak Bridge Road, Tulsa OK
Terry Kalkas, 402 ma Road, ma Falls pa
Eric Adams, 20 Post Road, Sudbury ma
Hubert Sims, 328A Brook Road, Roanoke VA
Amy Wilde, 334 ma Pkwy, Mountain View CA
Sal Carpenter, 73 ma Street, Boston ma

3.2 使用脚本文件:当有多个要编辑的项目时,可以将编辑命令放进一个脚本里,再使用sed搭配 -f 选项

-f<script文件>--file=<script文件> 以选项中指定的script文件来处理输入的文本文件

[root@localhost ~]# vim sed.sh
s/MA/ma/ 
s/PA/pa/ 
s/Ro/ro/ 
s/VA/va/ 
s/Br/br/
 
[root@localhost ~]# sed -f sed.sh test.txt
ma Daggett, 341 King road, Plymouth MA
Alice Ford, 22 East broadway, Richmond va
ma Thomas, 11345 Oak bridge road, Tulsa OK
Terry Kalkas, 402 Ma road, mA Falls pa
Eric Adams, 20 Post road, Sudbury mA
Hubert Sims, 328A brook road, Roanoke va
Amy Wilde, 334 Ma Pkwy, Mountain View CA
Sal Carpenter, 73 ma Street, Boston MA

[root@localhost ~]# sed -f sed.sh test.txt >sed.txt
[root@localhost ~]# cat sed.txt
ma Daggett, 341 King road, Plymouth MA
Alice Ford, 22 East broadway, Richmond va
ma Thomas, 11345 Oak bridge road, Tulsa OK
Terry Kalkas, 402 Ma road, mA Falls pa
Eric Adams, 20 Post road, Sudbury mA
Hubert Sims, 328A brook road, Roanoke va
Amy Wilde, 334 Ma Pkwy, Mountain View CA
Sal Carpenter, 73 ma Street, Boston MA

4.指定地址

  • 地址用于决定对哪些行进行编辑。地址形式可以是数字、正则表达式或二者的结合。
  • 如果没有指定地址,sed将处理输入文件中的所有行。
[root@localhost ~]# head /etc/passwd > passwd.txt    //生成测试文件

[root@localhost ~]# sed -r '1d' passwd.txt    //d:表示删除--1d表示删除文件的第1行 
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
....

[root@localhost ~]# sed -r '1,2d' passwd    //删除文件的1-2行
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
....

查找替换:
[root@localhost ~]# sed -r 's#/sbin/nologin#/bin/sh#g'  passwd.txt
//或者 sed -r 's/\/sbin\/nologin/\/bin\/sh/g'  passwd.txt
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/bin/sh
daemon:x:2:2:daemon:/sbin:/bin/sh
adm:x:3:4:adm:/var/adm:/bin/sh
....



[root@localhost ~]# sed -r '2,$d' passwd.txt    //删除第2行到最后一行
root:x:0:0:root:/root:/bin/bash 

[root@localhost ~]# sed -r '/^root/d' passwd.txt    //匹配到root开头的行,删除此行
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

....

[root@localhost ~]# sed -r '/nologin/d' passwd.txt    //含有nologin的行都删除
root:x:0:0:root:/root:/bin/bash
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
tang:x:1000:1000:tang:/home/tang:/bin/bash

[root@localhost ~]# sed -r '/bash/,3d' passwd.txt    //匹配到bash行删除,(匹配到bash行在第一行则)到此行的第3行删除
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
....

[root@localhost ~]# sed -r '/^root/,3d'  passwd.txt    //匹配到root开头行,一直删除到【匹配行之后的三行】
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
....

[root@localhost ~]# cat -n passwd.txt    //查看的同时并打印行号
    1 root:x:0:0:root:/root:/bin/bash
    2 bin:x:1:1:bin:/bin:/sbin/nologin
    3 daemon:x:2:2:daemon:/sbin:/sbin/nologin
    ....
    
[root@localhost ~]# sed -r '1~2d' passwd.txt    //删除奇数行,表示从第1行开始,每隔2行匹配一次
bin:x:1:1:bin:/bin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
halt:x:7:0:halt:/sbin:/sbin/halt
operator:x:11:0:operator:/root:/sbin/nologin

[root@localhost ~]# sed -r '0~2d' passwd.txt    //删除偶数行,表示从第0行开始,每隔2行匹配一次
root:x:0:0:root:/root:/bin/bash
daemon:x:2:2:daemon:/sbin:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin

5.sed流编辑器

5.1 插入命令,i(用的不少)

//在第2行前插入
[root@localhost ~]# sed -r '2i2222' passwd.txt
root:x:0:0:root:/root:/bin/bash
2222
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
....

[root@localhost ~]# sed -r '2i222222\
3333333\
4444444' passwd.txt
//或者 sed -r '2i11111111\naaaaaaaaaa\nbbbbbbbbb' passwd.txt

root:x:0:0:root:/root:/bin/bash
222222
3333333
4444444
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
....

5.2 修改命令,c(用得不少)

//第二行修改成text
[root@localhost ~]# sed -r '2c\text' passwd.txt
root:x:0:0:root:/root:/bin/bash
text
daemon:x:2:2:daemon:/sbin:/sbin/nologin
....

5.3 选项 -i 会使得sed用修改后的数据替换原文件(频繁使用)

[root@localhost ~]# sed -ri '3c\dameon:test' passwd.txt    //修改
[root@localhost ~]# sed -ri 's/SELINUX=enabled/SELINUX=disabled/' /etc/sysconfig/selinux    //替换

5.4 .bak备份

由于在使用 -i 参数时比较危险, 所以我们在使用i参数时在后面加上.bak就会产生一个备份的文件,以防后悔

[root@localhost ~]# sed -ri.bak 's/root/ROOT/gi' passwd.txt

5.5 调用变量

sed如果在脚本中使用的话,不可避免的要调用变量,所以以下这种方式可以用来调用变量

[root@localhost ~]# vim seed.sh
#!/usr/bin/bash
test=hello
echo "$test world" | sed "s/$test/HELLO/"
[root@localhost ~]# bash seed.sh

HELLO world

[root@localhost ~]#
 se_en=(SELINUX=enforcing)
[root@localhost ~]# se_ds=(SELINUX=disabled)
[root@localhost ~]# echo $se_en|sed "s/$se_en/$se_ds/"

6.常用操作(重点)

[root@localhost ~]# cp /etc/ssh/ssh_config .

6.1 删除配置文件中 # 号注释的行

[root@localhost ~]# sed -ri '/^#/d' ssh_config

6.2 用sed删除所有空行

[root@localhost ~]# cat sshd_config
HostKey /etc/ssh/ssh_host_rsa_key
HostKey /etc/ssh/ssh_host_ecdsa_key
HostKey /etc/ssh/ssh_host_ed25519_key

[root@localhost ~]# sed -ri '/^$/d' sshd_config
[root@localhost ~]# cat sshd_config
HostKey /etc/ssh/ssh_host_rsa_key
HostKey /etc/ssh/ssh_host_ecdsa_key
HostKey /etc/ssh/ssh_host_ed25519_key

问题:为什么匹配的是$呢?

[root@localhost ~]# vim sshd_config
HostKey /etc/ssh/ssh_host_rsa_key$
$        #添加了几行空行
$
$

:set list    #用set list就能看出,空行的结尾符就是$

6.3 用sed删除所有行

[root@localhost ~]# sed -ri.bak 'd' sshd_config
[root@localhost ~]# cat sshd_config
//或者直接用echo > sshd_config

6.4 给指定的行添加注释:

[root@localhost ~]# sed -r '2,5s/^/#/g' sshd_config
HostKey /etc/ssh/ssh_host_rsa_key
#HostKey /etc/ssh/ssh_host_ecdsa_key
#HostKey /etc/ssh/ssh_host_ed25519_key
#SyslogFacility AUTHPRIV
#AuthorizedKeysFile     .ssh/authorized_keys
PasswordAuthentication yes

6.5 给文件行添加和取消注释

[root@localhost ~]# cp /etc/yum.repos.d/CentOS-Base.repo  .
//添加注释
[root@localhost ~]# sed -r 's/^baseurl/#baseurl/g'  CentOS-Base.repo
//取消注释(注意空格)
[root@localhost ~]# sed -r 's/^# CentOS-Base.repo/CentOS-Base.repo/g'  CentOS-Base.repo    

6.6 删除配置文件中tab键开头的行

[root@localhost ~]# cat -n test.txt
     1  # CentOS-Base.repo
     2          CentOS-Base.repo
     3
     4
     5  #
     6  # The mirror system uses the connecting IP address of the client and the
     7  # update status of each mirror to pick mirrors that are updated to and
     8  # geographically close to the client.  You should use this for CentOS updates

[root@localhost ~]# sed -r '/^[\t]/d'  test.txt
# CentOS-Base.repo


#
# The mirror system uses the connecting IP address of the client and the
# update status of each mirror to pick mirrors that are updated to and
# geographically close to the client.  You should use this for CentOS updates
文章来源:https://blog.csdn.net/m0_62396418/article/details/135594375
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。