【系统运维】文本流编辑器工具sed命令使用教程

TangLu 未命名 2022-05-07 18198 0

一、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    #在每行第二个字母前加注释

评论