sed 命令
sed是一种文本流编辑工具,可以一行一行的处理文件内容
工作原理
Sed是从文件或管道中读取一行,处理一行,输出一行,直到最后一行。每当处理一行时,把当前处理的行存储在临时缓冲区中,称为模式空间(Pattern Space)。
接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。接着处理下一行,这样不断重复,直到文件末尾。一次处理一行的设计模式使得sed性能很高,sed在读取大文件时不会出现卡顿的现象。
基本语法
sed可以对文字进行增删改查
基本语法
sed 选项 "处理命令" 文件
常用选项
选项 | 描述 |
---|---|
-n | 关闭sed默认输出功能,只输出script处理过的信息 |
-e | 指定多个script指令,多点匹配 |
-f | 从指定文件读取script指令 |
-r | 识别扩展正则表达式 |
-i<备份后缀> | sed默认处理数据不影响文件原内容,-i 参数编辑文件并备份原文件,如:-i.bak |
处理命令
指令 | 描述 |
---|---|
p | 输出script处理的数据行 |
Ip | I 参数忽略过滤信息大小写 |
d | 删除模式匹配的行 |
a\ | 模式匹配的行后面追加内容信息,并处理下一行 |
i\ | 模式匹配的行前面追加内容信息,并处理下一行 |
c\ | 替换指定整行信息 |
w file | 保存模式匹配的行至指定文件 |
r file | 读取指定文件的文本至模式空间中匹配到的行后 |
= | 显示匹配到信息所在行号 |
! | 取反 |
; | 同参数 -e |
搜索替换格式:s/正则表达式/替换内容/修饰符
修饰符 | 描述 |
---|---|
无修饰符 | 表示只替换每一行第一个匹配到的文本 |
g | 表示行内全面替换,不输出文本,Ng表示替换匹配到的前N行 |
p | 表示打印替换后文本 |
w | 表示被替换信息写入一个文件 |
I / i | 替换忽略字母大小写 |
处理地址
处理地址 | 描述 |
---|---|
无地址 | 对文件全文处理 |
n | 指定第几行处理 |
$ | 处理文件最后一行 |
/regexp/ | 正则匹配,匹配到的文本处理。加上 -r 参数,支持扩展正则表达式 |
n,m | 范围匹配,指定从n行到m行文本处理 |
n,+m | 范围匹配,指定从n行到n+m行文本处理 |
/regexp1/ , /regexp2/ | 范围匹配,指定从regexp1匹配到行到regexp2匹配到行处理 |
n,/regexp/ | 范围匹配,指定从n行到regexp匹配到行处理 |
n~m | 步长匹配,1~2 表示从第一行过滤奇数行,2~2表示过滤偶数行 |
基本操作
文字打印
1)把文件全文内容输出俩遍
sed "p" /etc/passwd
2)只打印输出处理的数据文本行
sed -n "p" /etc/passwd
匹配地址
输出/etc/passwd文件的第10行
sed -n "10p" /etc/passwd
打印文件的最后一行文本
sed -n "$p" /etc/passwd
打印第一到第五行信息
sed -n '1,5p' /etc/passwd
练习:打印第一行到最后一行信息
sed -n '1,$p' /etc/passwd
打印第五行后面三行信息
sed -n '5,7p' /etc/passwd
sed -n '5,+2p' /etc/passwd
练习:打印第五行到最后一行信息
sed -n '5,$p' /etc/passwd
打印奇数行
n~m n开始数,m代表步长
seq 10|sed -n '1~2p'
seq 100 | sed -n '0~2p' | tr '\n' '+' | grep -o '[0-9].*[0-9]'|bc
seq 100 | sed -n '0~2p' | tr '\n' '+' | sed "s/+$//" |grep ""| bc
正则表达式
匹配字母d开头的行到字母n结尾的行,打印俩行之间文本
sed -n '/^d/,/n$/p' /etc/passwd
打印第三行到字母m开头的行
sed -n '3,/^m/p' /etc/passwd
匹配字母b开头的行到字母s开头的行
sed -n '/^b/,/^s/p' /etc/passwd
忽略大小写
sed -n '/ROOT/Ip' /etc/passwd
多点匹配
sed -e 执行多个script进行匹配文件内容,或者关系
打印/etc/passwd文件的第五行和第七行内容
sed -n '5p;7p' /etc/passwd
sed -n -e '5p' -e '7p' /etc/passwd
打印root开头行或者以nologin结尾的行
sed -n "/^root/p;/nologin$/p" /etc/passwd
sed -n -e "/^root/p" -e '/nologin$/p' /etc/passwd
显示行号
sed -n '/root/=' /etc/passwd
案例:匹配有root或bin的行
sed -n '/\(root\|bin\)/p' /etc/passwd
sed -n '/root/p;/bin/p' /etc/passwd
sed -n -e '/root/p' -e '/bin/p' /etc/passwd
打印有至少连续2个数字的行
sed -n -r '/[0-9]{2,}/p' test.txt
打印包含负数或小数的行
sed -n -r -e '/-[0-9]+/p' -e '/[0-9]+\.[0-9]+/p' test.txt
打印本机IP地址
ifconfig | sed -n '/broadcast/p' | egrep -o '([0-9]{1,3}\.){3}[0-9]{1,3}' | head -1
匹配#注释的行
sed -n '/^#/p' test.txt
匹配html注释的行
sed -n '/<!--.*-->/p' test.txt
匹配Email 字母数字两位以上@字母数字两位以上.com
sed -n -r '/[a-zA-Z0-9]{2,}\@[a-zA-Z0-9]{2,}\.(com|com.cn)/p' test.txt
删除操作
删除文件指定行
sed '2d' /etc/passwd
删除文件第二行到第六行
sed '/2,6/d' /etc/passwd
删除以字母d开始的行到以m开头的行,如果只匹配到字母d开头,文件末尾也没有匹配到字母m开头,则删除字母d到文件末尾
sed '/^d/,/^m/d' /etc/passwd
修改文件
先保存到passwd.bak文件中,再删除passwd文件有root的行
sed -i.bak '/root/d' passwd
注意:-i 和 -n 不要一起使用,会清空原文件
把my.cnf文件端口port的行删除
sed -i '/port/d' my.cnf
删除my.cnf中[mysqld]和[mysql]之间的内容
sed -i '/^\[mysqld\]/,/^\[mysql\]/d' my.cnf
追加操作
在/etc/passwd文件的第五行后追加一行信息“this is test append”
sed "5a\this is test append" /etc/passwd
在/etc/passwd文件中以root开头的行追加一行信息“this is test append”
sed -n "/^root/a\this is test append" /etc/passwd
seq 15 | sed '5,10a hello'
插入操作
在/etc/passwd文件的第三行前插入信息“this is test insert”
sed '3i\this is test insert' /etc/passwd
在/etc/passwd文件中以root开头的行前插入信息 “this is test insert”
sed '/root/i\this is test insert' /etc/passwd
seq 10 | sed -e '5i\123' -e '5a\456'
替换操作
指令c,表示把匹配到一整行信息替换
把第四行信息替换为“this is test replace”
seq 10 | sed "4c\this is test replace"
正则匹配到的整行替换
seq 10 | sed -r "/[235]/c\this si test replace"
搜索替换
s#要搜索的文字#要替换的文字#修饰符(g)
把/etc/passwd文件中的nologin替换为“this is test sub”
sed 's#nologin$#this is test sub#g' /etc/passwd
替换指令 g:表示把文件中匹配到所有字符串进行替换为目标信息
替换指令 p:配合参数 -n ,只打印被替换信息
sed -n 's#nologin$#this is test sub#gp' /etc/passwd
替换指令 w:被替换信息保存到指定文件
sed -n 's#nologin$#this is test sub#gw /data/sub.log' /etc/passwd
也可以使用: s/正则表达式要替换文字/替换后的文字/g
写入文件
把/etc/passwd文件中以nologin结尾的行写入到/data/nologin.log文件
sed -n '/nologin$/w /data/nologin.log' /etc/passwd
sed -n '/^b/w /data/sed.log' /etc/passwd
sed -n '1w /data/sed.log' /etc/passwd
sed -n '1,5w /data/sed.log' /etc/passwd
注意:指令w 是覆盖原文件内容,写入新内容
读入文件
把/etc/issue文件内容读入到/etc/passwd文件以root开头的行的后面
sed '/^root/r /etc/issue' /etc/passwd
把文件内容读写奇数行
sed '1~2r /etc/issue' /etc/passwd
[root@centos7 ~]#sed '/^b/,/^s/r /etc/issue' /etc/passwd
搜索取反
打印/etc/passwd文件中不是以nologin结尾的行
注意:使用单引号,双引号会把!p认为执行历史命令,建议使用单引号
sed -n '/nologin$/!p' /etc/passwd
sed -n '/root/!p' /etc/passwd
把/etc/fstab文件非注释行添加注释,包括空行
方法一: sed -r '/^#/!s/(.*)/#\1/p' /etc/fstab
方法二: sed -r '/^#/!s/^/#/p' /etc/fstab
引用变量
sed表达式可以使用单引号来引用,但是如果表达式内部包含变量字符串,就需要使用双引号。
test=hello
echo hello WORLD | sed "s/$test/HELLO/"
HELLO WORLD