Linux | sed文本处理,从入门到精通,看这一篇就够了
目录
模式空间(pattern space)和暂存空间(hold space)相关的命令
sed的用途
sed在处理文本时是逐行读取文件内容,读到匹配的行就根据指令做操作,不匹配就跳过。
sed是Linux下一款功能强大的非交互流式文本编辑器,可以对文本文件进行增、删、改、查等操作,支持按行、按字段、按正则匹配文本内容,灵活方便,特别适合于大文件的编辑。
Linux sed 命令是利用脚本来处理文本文件。
sed 可依照脚本的指令来处理、编辑文本文件。
Sed 主要用来自动编辑一个或多个文件、简化对文件的反复操作、编写转换程序等。
sed的语法命令格式
sed [选项] sed编辑命令 输入文件
shell命令 sed [选项] sed编辑命令
sed [选项] -f sed脚本文件 输入文件
sed [-hnV][-e<script>][-f<script文件>][文本文件]
sed的常用选项
- -e<script>或--expression=<script> 它告诉sed将下一个参数解释为一个sed指令,只有当命令行上给出多个sed指令时才需要使用-e选项
- -f<script文件>或--file=<script文件>后跟保存了sed指令的文件, 以选项中指定的script文件来处理输入的文本文件。
- -h或--help 显示帮助。
- -n或--quiet或--silent 取消默认输出,sed默认会输出所有文本内容,使用-n参数后只显示处理过的行
- -V或--version 显示版本信息。
- -i:直接对内容进行修改,不加-i时默认只是预览,不会对文件做实际修改
- -r:支持扩展正则
sed的常用编辑命令
- a :新增, a 的后面可以接字串,而这些字串会在新的一行出现(目前的下一行)~
- c :取代, c 的后面可以接字串,整行替换
- d :删除,删除指定行delete,所以 d 后面通常不接任何咚咚;
- i :插入, i 的后面可以接字串,而这些字串会在新的一行出现(目前的上一行);
- p :打印,亦即将某个选择的数据印出。通常 p 会与参数 sed -n 一起运行~
- s :取代,字符串替换,通常这个 s 的动作可以搭配正规表示法!例如 1,20s/old/new/g 就是啦!
- =:输出行号
- r:将文件的内容读入 read
- w:将文本写入文件 write
sed的p命令实例
显示第5行
sed -n '5p' /etc/passwd
显示第1至5行
sed -n '1,5p' /etc/passwd
显示第1行和第5行
sed -n '1p;5p' /etc/passwd
取反,取1到4行
cat -n /etc/passwd|sed -n '5,100!p'
显示第2行和其后面两行
sed -n '2,+2p' /etc/passwd
显示最后一行
sed -n '$p' /etc/passwd
从第一行起,每间隔3行输出一行
sed -n '1~3p' /etc/passwd
sed里单引号和双引号的区别
双引号里可以使用shell里的变量,单引号不行,双引号和单引号里都可以存放模式
[root@changjinhu ~]# sed -n "${a},${b}p" /etc/passwd
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
[root@changjinhu ~]# sed -n '${a},${b}p' /etc/passwd
sed:-e 表达式 #1,字符 0:未匹配的“{”
sed的s命令
在2到10行前面加上注释
sed -n '2,10s/^/#/p' passwd
在每行末尾加上?
sed -n 's/$/?/p' passwd
将/etc/selinux/config的SELINUX参数改为disabled
sed -n '/^SELINUX=/ s|enforcing|disabled|p' /etc/selinux/config
sed的s命令可以使用任意分隔符作为定界符
以/作为分隔符
sed -n '/^hello/s/\/bin\/bash/\/sbin\/nologin/p' /etc/passwd
以|作为分隔符
sed -n '/^hello/s|/bin/bash|/sbin/nologin|p' /etc/passwd
以:作为分隔符
sed -n '/^hello/s:/bin/bash:/sbin/nologin:p' /etc/passwd
sed的s命令中支持\t \n
sed -n 's/^xixi/\n1111111111111111/p' /etc/passwd
sed -n 's/^xixi/\t1111111111111111/p' /etc/passwd
sed 's/^abrt.*/&\n/' passwd
sed的c命令实例
更改整行操作可以根据行号和模式匹配进行操作
将id:所在的行整行替换成后面的字符串
sed '/id:/c id:5:initdefault:' /etc/inittab
将第3行改成后面的字符串
sed '3c ONBOOOT=no' ifcfg-eth0
sed的r命令实例
读入操作可以根据行号和模式匹配进行操作
在fstab文件的末尾后面读入hosts文件的内容
sed '$r /etc/hosts' /etc/fatab
df -h |sed '/dev/sda1/r /etc/mtab'
sed的a命令实例
追加操作可以根据行号和模式匹配进行操作
在第一行下新起一行追加后面的字符串
sed '1a aaaaaaaaaaaa' /etc/fstab
在包含boot的行下面追加后面的字符串
sed '/boot/r aaaaaaaaaa' /etc/fstab
sed的i命令实例
插入操作可以根据行号和模式匹配进行操作
在最后一行的前面插入后面的字符串
sed '$i 1111111111111' /etc/fstab
在包含defaults的行前面插入后面的字符串
sed '/defaults/i 1111111111111' /etc/fstab
sed的d命令实例
删除操作可以根据行号和模式匹配进行操作
删除第3到5行
sed '3,5d' /etc/fstab
删除包含2的行
sed '/2/d' /etc/fstab
除了包含ext3的行都删
sed '/ext3/!d' /etc/fstab
删除空行和注释
sed -r '/^$|^#/d' /etc/inittab
sed -e '/^$/d' -e '/^#/d' /etc/inittab
sed -r '/^$/d;/^#/d' /etc/inittab
sed中的&的用法
&用于表示替换命令中的匹配模式
[root@changjinhu ~]# echo 'I have a fat cat' | sed 's/.at/".at"/g'
I have a ".at" ".at"
[root@changjinhu ~]# echo 'I have a fat cat' | sed 's/.at/"&"/g'
I have a "fat" "cat"
在所有三位数字后面加个0
[root@changjinhu ~]# sed -nr 's/\<[0-9]{3}\>/&0/gp' /etc/passwd
games:x:12:1000:games:/usr/games:/sbin/nologin
systemd-coredump:x:9990:9970:systemd Core Dumper:/:/sbin/nologin
systemd-resolve:x:1930:1930:systemd Resolver:/:/sbin/nologin
polkitd:x:9980:9960:User for polkitd:/:/sbin/nologin
unbound:x:9970:9940:Unbound DNS resolver:/etc/unbound:/sbin/nologin
sssd:x:9960:9930:User for sssd:/:/sbin/nologin
rngd:x:9950:9920:Random Number Generator Daemon:/var/lib/rngd:/sbin/nologin
mysql:x:9940:1790::/home/mysql:/bin/false
sed命令标签的用法
标签:sed使用圆括号定义替换模式中的部分字符;相当于python里的正则分组
标签可以方便在后面引用,每行指令最多添加9个指令,相当于python里的引用分组
例如:
sed -r 's/(^[[:alnum:]]+)(.*)/\1/' /etc/passwd
sed -r 's/(^[[:alnum:]]+)(.*)/\2/' /etc/passwd
echo aaa bbb ccc | sed -r 's/([a-z]+)([a-z]+)([a-z]+)/\3 \2 \1/'
模式空间(pattern space)和暂存空间(hold space)相关的命令
n 输出模式空间行,读取下一行替换当前模式空间的行,执行下一条处理命令而非第一条命令。
N 读入下一行,追加到模式空间行后面,此时模式空间有两行。
h 把模式空间里的行拷贝到暂存空间。
H 把模式空间里的行追加到暂存空间。
g 用暂存空间的内容替换模式空间的行。
G 把暂存空间的内容追加到模式空间的行后。
x 将暂存空间的内容于模式空间里的当前行互换。
!对所选行以外的所有行应用命令。
d)删除模式空间的内容并导致读入新的输入行,从而在脚本的顶端重新使用编辑方法
D)删除模式空间中直到第一个嵌入的换行符的这部分内容。它不会导致读入新的输入行,相反,它返回到脚本的顶端,将这些指令应用于模式空间剩余的内容
注意:暂存空间里默认存储一个空行。
2!G 不是第二行的时候进行G操作
$!d 不是最后一行的时候进行d操作,是最后一行就不进行d操作
行号是sed读取文件里的第几行
sed工具的执行流程
sed编辑器逐行处理文件,并将输出结果打印到屏幕上。sed命令将当前处理的行读入模式空间(pattern space)进行处理,sed在该行上执行完所有命令后就将处理好的行打印到屏幕上(除非之前的命令删除了该行),sed处理完一行就将其从模式空间中删除,然后将下一行读入模式空间,进行处理、显示。处理完文件的最后一行,sed便结束运行。sed在临时缓冲区(模式空间)对文件进行处理,所以不会修改原文件,除非显示指明 -i 选项。
sed工具的执行原理
1.在每行前面加一个字符串sanchuang2.自己编辑一个文件test.txt,内容如下:
0.0.0.0
1.1.1.1
2.2.2.2
输出以下形式:
0.0.0.0:80,1.1.1.1:80,2.2.2.2:80
[root@changjinhu ~]# cat test.txt
0.0.0.0
1.1.1.1
2.2.2.2
[root@changjinhu ~]# sed -i 'N;N;s/\n/:80,/g;s/$/:80/' test.txt
[root@changjinhu ~]# cat test.txt
0.0.0.0:80,1.1.1.1:80,2.2.2.2:80
将文件反转输出,实现tac功能
[root@changjinhu ~]# cat test.txt
0.0.0.0
1.1.1.1
2.2.2.2
[root@changjinhu ~]# sed '1!G;h;$!d' test.txt
2.2.2.2
1.1.1.1
0.0.0.0
练习
18/Dec/2021:16:55:48 起始时间
18/Dec/2021:17:26:30 结束时间
查找出以上2个时间点之间的日志,输出到屏幕
#1.字符串匹配
cat access.log|sed -n '/18\/Dec\/2021:16:55:48/,/18\/Dec\/2021:17:26:30/p'
#2.正则匹配
cat access.log -n |sed -nr '/18\/Dec\/2021:(16:55:(4[89]|5[0-9])|16:5[6-9]:[0-5][0-9]|17:[01][0-9]:[0-5][0-9]|17:2[0-5]:[0-5][0-9]|17:26:[0-2][0-9]|17:26:30)/p'
1.sed取出/etc/passwd文件的第一列
[root@jack 12-20]# sed -n 's/:/\n/p' passwd|sed -n '1~2p'
[root@jack 12-20] sed -n 's/:.*//gp' passwd
2.sed将PATH环境变量中的冒号换成换行->可以将PATH变量的内容重定向到一个文件里,例如path.txt
[root@jack 12-20]# sed -n 's/:/\\n/gp' path.txt
3.sed将PATH环境变量斜杠/换成斜杠\
[root@jack 12-20]# sed -i 's/\//\\/g' path.txt
4.sed修改SELINUX配置文件从开启(enforcing)变成禁用(disabled)/etc/sysconfig/selinux
[root@jack 12-20]# sed -i '/^SELINUX=/ s/enforcing/disabled/p' config
5.去掉/etc/passwd文件中第二个字段的x
[root@jack 12-20]# sed -n 's/:x:/::/pg' passwd
6.将/etc/sysconfig/network-scripts/ifcfg-ens33里的ONBOOT=no修改为yes或者修改下IPADDR后面的ip地址,具体ip自己定义
[root@jack 12-20]# sed -i '/ONBOOT=/ s/yes/no/' ifcfg-ens33
8.复制/etc/ssh/sshd config到当前目录下,修改里面的端口号修改为8899将#Port 22配置修改为Port 8899要求去掉前面的#号,将22修改为8899
[root@jack 12-20]# sed -i '/s/#Port 22/Port 8899/' sshd_config
更多推荐
所有评论(0)