【系统运维】文本流编辑器工具sed命令使用教程
一、sed命令介绍
sed是一种流编辑器工具,可以根据设置的匹配条件对文件内容进行处理,支持正则表达式。其工作流程和awk工具一样是采用逐行处理并输出的方式,awk和sed在应用场景上不同,awk主要用于对标准输出进行处理,sed更多是对文本内容进行处理。在进行sed处理的时候可以按照"将x行到y行中带有z字符的内容做a操作"从格式进行编写,如果需要引用变量使用双引号进行书写。sed命令格式如下:
#方式1
sed [options] '/pattern/command' file #如果有引用变量的话需要使用双引号
#方式2
stdout | sed [option] "pattern command"
二、sed命令常用选项(对应命令格式中的options)
-r:支持扩展正则表达式,如+、|、()等特殊符号
cat file | sed -nr '/=+/p' #打印出包含一个或多个=号的行
-i:不加-i时所作的操作都是不会修改源文件的,如果要修改源文件的话就需要加上这个参数。这里有个备份文件的小技巧:为避免误操作直接覆盖了源文件,我们可以在加-i的时候加上.bak,然后就会自动生成一个以.bak结尾的备份文件,如图:
-n:不显示默认的输出结果。由于sed在进行文本处理的时候会把每一行文本进行一次输出,如果该行经过了处理还会输出2次,如果文本内容非常多的话就会带来大量的冗余信息,所以通常会使用-n选项并结合p命令仅显示处理过的内容
#比如单独显示某一行数据
cat file | sed -n '4p'
-e:多重匹配,第二次匹配时模式空间里的数据是第一次替换后的
sed -e 's/tom/TOM/' -e 's/tom/jerry/' /etc/passwd
#由于第一次匹配时把tom换成了TOM,第二次就不存在tom字段,所以不会再替换为jerry
sed 's/tom/TOM/;s/tom/jerry/' /etc/passwd #分号也可以代替-e选项
三、sed定址(即匹配条件)(对应命令格式中的pattern部分)
sed可以使用正则表达式进行定址以决定需要处理的内容范围,
# 10command 仅匹配第10行
# 10,20command 匹配10到20行
# 10,+5command 在10行的位置再多打印三行
# /pattern1/command 使用//后就可以进行正则匹配,也是sed使用最多的定址方式
# /pattern1/,/pattern2/command 从第一个正则内容匹配到第二个正则内容出现的地方
# 10,/pattern/ 从第10行开始匹配,直到pattern所在行
sed -n '17p' 1.txt #打印17行
sed -n '10,20p' 1.txt #打印10-20行
sed -n '/root/p' 1.txt #打印包含root的行
sed -n '/14:00/,/14:30/p' /var/log/messages #过滤指定日期的日志
四、sed动作命令(对应命令格式中的command部分)
p:打印匹配出来的内容,也是sed的默认命令
d:删除匹配到的内容,指定行数或者通过正则表达式都可以匹配,并且可以组合进行区间匹配
#删除指定行
sed -i '15d' /etc/passwd #/etc/passwd中的第15行
sed -i '8,14d' passwd ##删除/etc/passwd中的第8行到第14行的所有内容
#删除包含过滤条件的行 /pattern1/d
sed -i '/\/sbin\/nologin/d' /etc/passwd #删除/etc/passwd中的不能登录的用户(筛选条件:/sbin/nologin)
sed -i '/^mail/,/^yarn/d' passwd #删除/etc/passwd中以mail开头的行,到以yarn开头的行的所有内容
sed -i '/\/sbin\/nologin/,13d' passwd #删除/etc/passwd中第一个不能登录的用户,到第13行的所有内容
#删除/etc/passwd中第5行到以ftp开头的所有行的内容
sed -i '5,/^ftp/d' passwd
#删除/etc/passwd中以yarn开头的行到最后行的所有内容
sed -i '/^yarn/,$d' passwd
#删除配置文件中的所有注释行和空行
sed -i '/[:blank:]*#/d;/^$/d' nginx.conf
#在配置文件中所有不以#开头的行前面添加*符号,注意:以#开头的行不添加
sed -i 's/^[^#]/\*&/g' nginx.conf
s:将查找出来的内容进行替换
用///或###(其它任意成对的符号都可以)引用替换前和替换后的内容,如s/old/new/或s#old#new#这两种写法都可以把old一词替换为new。old部分可以用正则表达式匹配,new不可以
sed '1,2s/tom/TOM/' /etc/passwd #把第1、2行的第一个tom替换为TOM
sed '/root/s/root/ROOT/' /etc/passwd #匹配包含root的行,并把root替换ROOT
sed 's/root/tanglu/ig' /etc/passwd #将全文中的root替换为tanglu,i代表不区分大小写,g代表全局替换
sed -ir '1,10s/^/#/' /etc/fstab #批量增加注释的最简洁办法
old_str=hadoop
new_str=HADOOP
sed -i "s/'$old_str'/'$new_str'/g" str.txt
q:退出命令
由于sed工作模式是将文件的每一行都处理后再进行输出,那么当遇到处理巨大文件时就会耗费很多时间,这可能是不必要的,比如我们明确只需要处理该文件的前100行。这个时候就可以用上该选项了,示例:
cat bigfile | sed '1,100d;100q' #处理到第100行后就退出
a:在每个符合条件的行后面追加一行内容
i:在每个符合条件的行前面追加一行内容
cat shell.sh | sed -i '1i#!/bin/bash' #给脚本增加一行注释
r:将r读取到的文件写入到匹配行的后面
w:将匹配行写入到w所指定的文件
sed -i '10,20w /tmp/test.txt' /etc/passwd
sed的后项引用
括号内的部分可以在后面直接被引用,第一个括号内的内容是\1,依次类推,也可以使用&符号代表前面所匹配到的所有内容。后项引用可用于更换文本内容的位置或者批量添加注释等
sed -r 's/(.)(.)(.*)/\1\2#\3/' /etc/fstab #在每行第二个字母前加注释
评论