shell法宝之sed,修改文件内容的好帮手
Posted 丁CCCCC
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了shell法宝之sed,修改文件内容的好帮手相关的知识,希望对你有一定的参考价值。
sed编辑器
一、概述
- sed是一种流编辑器,会在编辑数据之前基于预先提供的一组规则来编辑数据流
- sed编辑器可以根据命令来处理数据流中的数据,这些命令要么从命令行中输入,要么存储在一个命令文本中
1.1 工作流程
读取、执行、显示
- 读取:sed从输入流(文件、管道、标准输入)中提取一行内容存储到临时的缓冲区
- 执行:默认情况下,所有的sed命令都在缓冲区内执行,除非指定行的地址,否则sed将会在所有行上依次执行
- 显示:发送修改后的内容到输出流,发送数据后,缓冲区清空,所有的文件内容处理完之前,上述过程将会一直重复执行,直到内容被处理完
默认情况下所有的命令都是在缓冲区完成,所有输入的文件本身不会发生变化,除非我们手动进行重定向存储
1.2 命令格式
- 第一种
sed -e '操作' 文件1 文件2 ...
sed -n -e '操作' 文件1 文件2 ...
sed -f 脚本文件 文件1 文件2
sed -i -e '操作' 文件1 文件2 ...
- 第二种
sed -e 'n{
操作1
操作2
...
}' 文件1 文件2 ...
二、常用选项
选项 | 解释 |
---|---|
-e 或 - -expression= | 表示用指定命令来处理输入的文本文件,只有一个操作命令时可省略,一般在执行多个操作命令使用 |
-f 或 - -file= | 用指定的脚本文件来处理输入的文本文件 |
-h 或 - -help | 显示帮助 |
-n、- -quiet 或 silent | 禁止 sed 编辑器输出,但是可以与 p 命令一起使用完成输出 |
-i | 直接修改目标文本文件 |
三、常用操作
选项 | 解释 |
---|---|
s | 替换、替换指定字符 |
d | 删除、删除选定的行 |
a | 增加、在当前行下面增加一行指定内容 |
i | 插入、在选定行上面插入一行指定内容 |
c | 替换、将选定行替换为指定的内容 |
y | 字符转换、转换前后的字符长度必须相同 |
p | 打印、如果同时指定行,表示打印行;如果不指定行,则表示打印所有内容;如果有非打印字符,则以 ASCII 码输出。通常与 “ -n ” 一起使用 |
= | 打印行号 |
l(小写L) | 打印数据流中的文本和不可打印的ASCII字符(比如结束符$、制表符 \\t ) |
四、命令代码的使用
4.1 打印内容
sed 'p' cc.sed # 打印文件内容
sed -ne 'p' cc.sed # 打印内容
sed -ne '=' cc.sed # -n显示行号,不显示内容
sed -ne 'l' cc.sed # 打印文本,包括不可打印的字符$
4.2 寻址方式
两种
- 以数字形式来表示区间
- 用文本模式来过滤出行
部分简易命令
以 “ cc.sed ” 文本为模板,按照以下命令完成需求
sed -n '1p' cc.sed # 打印第一行内容
1
sed -n '5p' cc.sed # 打印第五行内容
5
sed -n '$p' cc.sed # 打印最后一行,$代表最后
0
sed -n '2,5p' cc.sed # 打印2至5行的内容
2
3
4
5
sed -n '2,+5p' cc.sed # 打印第二行开始,往后数五行
2
3
4
5
sed -n '8,$p' cc.sed # 打印第八行到最后
6
7
8
9
0
sed -n 'p;n' cc.sed # 打印奇数行
1
3
5
7
9
sed -n 'n;p' cc.sed # 打印偶数行
2
4
6
8
0
sed -n '5,${n;p}' cc.sed # 从第五行开始,打印偶数行至最后
6
8
0
系统文件内过滤需求
- 过滤passwd文件内有root信息的
sed -n '/root/p' /etc/passwd # 搜索带有root信息
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
- 过滤 “ a ” 开头的行
sed -n '/^a/p' /etc/passwd # 以a开头的行
adm:x:3:4:adm:/var/adm:/sbin/nologin
abrt:x:173:173::/etc/abrt:/sbin/nologin
avahi:x:70:70:Avahi mDNS/DNS-SD Stack:/var/run/avahi-daemon:/sbin/nologin
apache:x:48:48:Apache:/usr/share/httpd:/sbin/nologin
- 过滤 “ nologin ” 结尾的行,$表示结尾
sed -n '/nologin$/p' /etc/passwd # 过滤noligin结尾的行,内容较多,筛选部分
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
- 查找 “ ftp ” 和 “ root ” 的相关行
第一种:
sed -n '/ftp\\|root/p' /etc/passwd # | 表示或,需要用反斜杠 \\ 来注释,否则无法检索
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
第二种:
sed -nr '/ftp|root/p' /etc/passwd # 使用-r命令可以不需要添加反斜杠
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
- 从搜索固定行数至内容的命令
sed -n '2,/sync/{=;p}' /etc/passwd # 从第二行打印到包含sync的则一行,配合-n可以看行号
2
bin:x:1:1:bin:/bin:/sbin/nologin
3
daemon:x:2:2:daemon:/sbin:/sbin/nologin
4
adm:x:3:4:adm:/var/adm:/sbin/nologin
5
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
6
sync:x:5:0:sync:/sbin:/bin/sync
- 根据检索条件匹配出内容,-r表示支持扩展正则表达式
[root@ccc lianxi]# sed -nr '/ro{1,}t/p' /etc/passwd # 匹配一位及以上o,得出结果rot和root都可以出来
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
4.3 删除方式
简单的几个命令
sed 'd' cc.sed # 删除所有内容
sed '5d' cc.sed # 删除第五行
1
2
3
4
6
7
8
9
0
sed '2,8d' cc.sed # 删除2到8行
1
7
8
9
0
sed '$d' cc.sed # 删除最后一行
1
2
3
4
5
6
7
8
9
[root@ccc lianxi]# # 删除空行
1
2
3
4
5
6
7
8
9
0
对系统文件做更改
- 删除passwd文件内 nologin 结尾的行
sed '/nologin$/d' /etc/passwd # 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
dcc:x:1000:1000:dcc:/home/dcc:/bin/bash
- 除了 nologin ,其他都删除
sed '/nologin$/!d' /etc/passwd # 只留下结尾 nologin 的行
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
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
-
从1开始删除,一直删除到4结束,不区分字符数量
模板
-
sed ‘/1/,/4/d’ cc.sed
-
删除从1开头的到4开头的行,和前面的删除1到4行有区别
4.4 替换
格式
行范围 s/旧字符串/新字符串/替换标记
替换标记
- 数字:表示新字符串将要替换到第几处所匹配的地方
- g:表面新字符串将要替换所有匹配的地方
- p:打印与替换命令相匹配的行,与 “ -n ” 共同使用
- w 文件:将替换的结果写到指定的文件中
模板
- 替换passwd文件内的 root 为 AAAAA
- 不加数字默认只会替换匹配到的第一个内容
- 按行匹配
sed -n 's/root/AAAAA/p' /etc/passwd # 替换root为AAAAA
AAAAA:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/AAAAA:/sbin/nologin
sed -n 's/root/AAAAA/2p' /etc/passwd # 加了数字2,只有一条符合条件(第二位root被替换)
root:x:0:0:AAAAA:/root:/bin/bash
- 匹配到的 root 全都替换 AAAAA
sed -n 's/root/AAAAA/gp' /etc/passwd # g代表全部替换
AAAAA:x:0:0:AAAAA:/AAAAA:/bin/bash
operator:x:11:0:operator:/AAAAA:/sbin/nologin
- 给行的开头添加 “ # ”
sed '1,5 s/^/#/' cc.sed # ^代表行首,1,5表示选中第1至5行
#1
#2
#3
#4
#5
6
7
8
- 给指定1开的行末尾加上 “ # ”
sed '/^1/ s/$/#/' cc.sed # ^代表开头,在匹配行的末尾加上#
1#
2
3
4
5
6
7
8
9
0
11#
22
- 将passwd文件内的第1-15行写入到新的文件中,并在开头加上#
sed '1,15 s/^/#/w ceshi.txt' /etc/passwd
cat ceshi.txt
#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:99:99:Nobody:/:/sbin/nologin
#systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin
#dbus:x:81:81:System message bus:/:/sbin/nologin
- 替换passwd文件内 bin/bash 为 bin/csh
- !号为字符串的分隔符
sed -n 's!/bin/bash!/bin/csh!p' /etc/passwd # !/bin/bash!为原有字符 /bin/csh!为新字符,用!号分隔开
root:x:0:0:root:/root:/bin/csh
dcc:x:1000:1000:dcc:/home/dcc:/bin/csh
123456:x:1001:1001::/home/123456:/bin/csh
ccd:x:1002:1002::/home/ccd:/bin/csh
ddccdd:x:1003:1003::/home/ddccdd:/bin/csh
dccccccc:x:1004:1004::/home/dccccccc:/bin/csh
ccccc:x:1005:1005::/home/ccccc:/bin/csh
ccaa:x:1006:1006::/home/ccaa:/bin/csh
ccaacc:x:1007:1007::/home/ccaacc:/bin/csh
dcc666:x:1008:1008::/home/dcc666:/bin/csh
ccaz:x:1009:1009::/home/ccaz:/bin/csh
- 将文本内74577更换为7676
sed -i 's7\\745\\7\\77\\76\\767g' cc.sed # s后面的7为分隔符,并不是我们认知的7,需要用\\来转义,后面出现的7同样需要,否则会和替换符重叠
cat cc.sed
1
2
3
5
2
6
7676
4.5 插入
- 将文件内第三行内容替换为 ABC
sed '/3/c ABC' cc.sed # 3表示第三行, c为替换
1
2
ABC
5
2
6
7676
- 替换文件内7676为ABCD
[root@ccc lianxi]# sed '/7676/ y/7676/ABCD/' cc.sed # 选定7676 替换,必须同样位数替换
1
2
3
5
2
6
ABAB
- 在文件内1到3行的下方插入ABCD
sed '1,3a ABCD' cc.sed # a为文件下方增加一行内容,i为文件上方增加
1
ABCD
2
ABCD
3
ABCD
5
- 将文件内第三行内容剪切到末尾
sed '/3/{H;d};$G' cc.sed # H表示复制,G表示粘贴,因为需求是剪切,所以需要用 d 删除原有的内容
1
2
5
2
6
7676
3
- 123ABC 对调为 CBA321
- 方法比较古板
echo "123ABC" | sed -r 's/(1)(2)(3)(A)(B)(C)/\\6\\5\\4\\3\\2\\1/'
CBA321
以上是关于shell法宝之sed,修改文件内容的好帮手的主要内容,如果未能解决你的问题,请参考以下文章