Sed工作原理
sed是一种流编辑器,它是文本处理中非常有用的工具,能够完美的配合正则表达式使用,处理时,把当前处理的行存储在临时缓冲区中,称为模式空间,接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。接着处理下一行,这样不断重复,直到文件末尾。文件内容并没有改变。
sed的特点:
- sed命令是将一系列的编辑命令应用于一批文本的理想工具。
- sed命令是一个非交互式的文本编辑器,它可以对来自文本文件以及标准输入的文进行编辑。其中,标准输入可以是来自键盘、文件重定向、字符串、变量或者是管道的文本。
- sed命令会从文件或者标准输入中一次读取一行数据,将其复制到缓冲区(最多8192字节),然后读取命令行或者脚本的编辑子命令,对缓冲区中的文本行进行编辑。重复此过程,一直到所有的文本行
都处理完毕
sed基本语法
sed OPTIONS… [SCRIPT] [INPUTFILE…]
选项 | 解析 |
---|---|
-n,-quiet,-silent | 不输出模式空间中的内容,使用安静模式,在一般sed的用法中,所有来自STDIN的数据一般都会被列出到屏幕上,但如果加上-n参数后,则只有经过sed特殊处理的那一行才会被列出来; |
-i | 直接编辑原文件,而不是由屏幕输出,默认不对原文件进行操作; |
-e | 直接在命令行模式上进行sed的动作编辑,多个子命令之间也可以用分号隔开; sed -e 'command1;command2… filename 或者 sed -e ‘command1’ -e ‘command2’……filename |
-r | 使用扩展正则表达式; |
-f | 直接将sed的动作写在一个文件内,-f filename则可以执行filename内的sed动作。 |
地址定界
定界符 | 解析 |
---|---|
#: | #为数字,指定要进行处理操作的行;1,表示第一行; |
$: | 表示最后一行,多个文件进行操作的时候,为最后一个文件的最后一行; |
/regexp/: | 表示能够被regexp匹配到的行; regexp即基于正则表达式的匹配; |
/regexp/I | :匹配时忽略大小写; |
%regexp% | : 任何能够被regexp匹配到的行,换用%(用其他字符也可以,如:#)为边界符号; |
addr1,addr2 | 指定范围内的所有的行(范围选定); 常用地址定界表示方式:0,/regexp/:从起始行开始到第一次能够被regexp匹配到的行。 /regexp/,/regexp/:被模式匹配到的行内的所有的行。 |
first~step | 指定起始的位置及步长,例如:1~2表示1,3,5… 8)addr1,+N:指定行以及以后的N行; addr1,~N:指定行开始的N行; |
注意事项:
- 如果没有指定地址,表示命令将应用于每一行
- 如果只有一个地址,表示命令将应用于这个地址匹配的所有行
- 如果指定了由逗号分隔的两个地址,表示命令应用于匹配第一个地址和第二地址之间的行(包括这
两行) - 如果地址后面跟有感叹号,表示命令将应用于不匹配该地址的所有行
常用编辑命令
编辑命令 | 解析 |
---|---|
d | 删除匹配到的行 |
p | 打印当前模式空间内容 |
a \text:append | 表示在匹配到的行之后追加内容 |
i \text:insert | 表示在匹配到的行之前追加内容 |
c \text:change | 表示把匹配到的行和给定的文本进行交换 |
s/regexp/replacement/flages | 查找替换,替换regexp匹配到的内容(其中/可以用其他字符代替, 例如@) 其他编辑命令: 常用的flages: g:全局替换,默认只替换第一个 i: 不区分大小写 p:如果成功替换则打印 |
r | 读入文件内容追加到匹配行后面 |
R | 读入文件一行内容追加到匹配行后面 |
y y/source/dest/ | 固定长度替换,要求替换的字符串长度相等 |
w /path/to/somefile | 将匹配到的文件内容追加到指定的文件末尾 |
测试用例:
[root@haha day7]# sed ' 1d ' test_txt
hello china
hello chongqing
hello shaanxi
welcom to shaanxi
welcom to beijing
[root@haha day7]# sed '1 ahehe' test_txt
hello world
hehe
hello china
hello chongqing
hello shaanxi
welcom to shaanxi
welcom to beijing
[root@haha day7]# sed '1 ihehe' test_txt
hehe
hello world
hello china
hello chongqing
hello shaanxi
welcom to shaanxi
welcom to beijing
[root@haha day7]# sed '1 chehe' test_txt
hehe
hello china
hello chongqing
hello shaanxi
welcom to shaanxi
welcom to beijing
[root@haha day7]# sed 'r' add_txt test_txt
hello lc
hello world
hello china
hello chongqing
hello shaanxi
welcom to shaanxi
welcom to beijing
sed扩展
特殊符号 | 说明 |
---|---|
! | 对指定行以外的所有行应用命令 |
= | 打印当前行行号 |
~ | “first~step”表示从first行开始,以步长step递增 |
& | 代表被替换的内容 |
; | 实现一行命令语句可以执行多条sed命令 |
{} | 对单个地址或地址范围执行批量操作 |
+ | 地址范围中用到的符号,做加法运算 |
[root@haha day7]# sed '1~1 s/hello//' test_txt
world
china
chongqing
shaanxi
welcom to shaanxi
welcom to beijing
[root@haha day7]# sed -n '2,4!{p;=}' test_txt
hello world
1
welcom to shaanxi
5
welcom to beijing
6
[root@haha day7]# sed -n '2,4 {s/hello/&to/;p}' test_txt
helloto china
helloto chongqing
helloto shaanxi
案例
1、删除/etc/grub2.conf文件中所有以空白开头的行行首的空白字符
sed 's/^[[:space:]]//' /etc/grub2.cfg
2、删除/etc/fstab文件中所有以#开头,后面至少跟一个空白字符的行的行首的#和空白字符
sed 's/^#" "+//' /etc/fstab
3、在/root/install.log每一 行行首增加#号
sed 's/^.*$/#&/' /root/.bashrc
4、在/etc/fstab文件中不以#开头的行的行首增加#号
sed 's/^[^#]/#&/' /etc/fstab
5、利用sed取出ifconfig命令中本机的IPv4地址
ifconfig |sed -n '2p' | sed -r "s/.*inet[[:space:]]*//" | sed -r "s/[[:space:]]*netmask.*//"
6、关闭本机SELinux的功能
sed 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config
7、在/etc/hosts配置文件中添加内容
sed '1 ilc' /etc/hosts