sed:stream editor 流编辑器。对标准输出或文件逐行进行处理。
Sed是从文件或管道中读取一行,处理一行,输出一行;再读取一行,再处理一行,再输出一行,直到 最后一行。每当处理一行时,把当前处理的行存储在临时缓冲区中,称为模式空间(Pattern Space),接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。接着处理下 一行,这样不断重复,直到文件末尾。一次处理一行的设计模式使得sed性能很高,sed在读取大文件时 不会出现卡顿的现象。如果使用vi命令打开几十M上百M的文件,明显会出现有卡顿的现象,这是因为 vi命令打开文件是一次性将文件加载到内存,然后再打开。Sed就避免了这种情况,一行一行的处理, 打开速度非常快,执行速度也很快
sed [OPTION]... 'script;script;...' [input-file]...
基本用法
OPTION:
- -n 不输出模式空间内容到屏幕,即不自动打印,如果不加-n,会自动打印每一行
- -e 当script有多个时,使用-e,多个script之间是或关系,
-e 'script1' -e 'script2'等同于'script1;script2' - -f file 从指定文件中读取script
- -r,-E 支持扩展正则表达式
- -i 对文件直接进行修改,而不是输出到终端
- -i.bak 先备份原文件再修改文件
script:
script是 地址 和 命令 的组合,地址用来定位,命令用来对定位的内容进行操作。
地址
-
不给地址:对全文进行处理
-
单地址:
- #:#是阿拉伯数数字,指定行
- $:最后一行
- /pattern/:匹配到的每一行
-
地址范围:
- #,#:第#行到第#行 3,6 从第3行到第6行
- #,+#:第#行开始,往后再匹配#行 3,+4 从第3行到第7行
- /pattern1/,/pattern2/:从pattern1匹配到行,到pattern2匹配到的行,再往下继续,从pattern1匹配到行,到pattern2匹配到的行...
-
步进:~
- first~step:匹配first行,然后步进为step向后继续匹配,例如 1~2 就是匹配奇数行、2~2就是匹配偶数行。
命令
-
p:print 打印查询的行
-
Ip:忽略大小写输出
-
d:删除匹配到的行
-
a:append,追加内容到下一行 \n表示换行; 如果要解析空格,需要用反斜杠\
-
i text:insert,在行前面插入内容
-
c text:change,替换行
-
w file:保存模式匹配的行到指定文件
-
r file:从file中读取内容,插入到匹配到的行的下一行
-
=:打印匹配到行的行号
-
! 命令:对没有匹配到的行进行处理,例如 !p 是打印未匹配到的行、!atext 是在未匹配到的行的下一行添加text
-
s/pattern/string/修饰符:查找替换 修饰符:
- g:一行里如果由多个匹配到的内容,全部替换。默认只替换第一个。
- p:打印替换成功的行
- w file:将成功替换的行保存至文件中
- I,i:忽略大小写
练习
1.将php.ini-production中的无关信息去掉
sed -E '/^; /d;/^;+;$/d' /usr/local/src/php-7.4.8/php.ini-production | uniq > php.ini
2.获取分区利用率
lujinkai@Z510:~$ df | sed -En '/^\/dev\/sd/s/.* ([0-9]+)%.*/\1/p'
3.取基名和目录名
# 使用/作为分隔符,如果搜索条件中出现/需要转义,所以为了易读性,不建议使用搜索条件中出现的字符作为分割符
pwd |sed -r 's/(^\/.*\/)([^\/]+\/?)/\2/' # 取基名
pwd |sed -r 's@(^/.*/)([^/]+/?)@\2@' # 取目录
4.将非#开头的行加#
lujinkai@Z510:~/data/test$ sed -Ei 's/^[^#].*/# &/' a.log
# 或
lujinkai@Z510:~/data/test$ sed -Ei 's/(^[^#].*)/# \1/' a.log
# 或
lujinkai@Z510:~/data/test$ sed -ri '/^#/!s/^/# /' a.log
5.将#开头的行删除#
lujinkai@Z510:~/data/test$ sed -ri 's/^#(.*)/\1/' a.log
高级用法
略。。。