sed 是非交互式的编辑器。它不会修改文件,除非使用 shell 重定向来保存结果。默认情况下,所有的输出行都会被打印到屏幕上。
sed 编辑器逐行处理文件(或输入),并将结果打印到屏幕上。
具体过程如下:首先 sed 把当前正在处理的行保存在一个临时缓存区中(也称为模式空间),然后处理临时缓冲区中的行,完成后把该行发送到屏幕上。
sed 每处理完一行就将其从临时缓冲区删除,然后将下一行读入,进行处理和显示。处理完输入文件的最后一行后,sed 便结束运行。sed 把每一行都存在临时缓冲区中,对这个副本进行编辑,所以直接使用不会修改原文件内容。
如果要修改原文件,需要添加 -i
选项。
输出文件内容
将 regular_express.txt 的内容列出并打印行号,并将 2-5 行删除显示:
bash
nl regular_express.txt | sed '2,5d'
2,5d
表示删除 2~5 行,d 即为 delete。
同理,删除第 2 行:
bash
nl regular_express.txt | sed '2d'
删除第三行到最后一行, $
表示定位到最后一行:
bash
nl regular_express.txt | sed '3,$d'
使用 -i
在原文件中删除第 1 行:(注意:该指令会修改原文件)
bash
sed -i '1d' regular_express.txt
使用 a 和 i 新增输出
在第二行后添加字符串 test:
bash
nl regular_express.txt | sed '2a test'
在第二行前添加字符串 test:
bash
nl regular_express.txt | sed '2i test'
在第二行后添加两行 test,\n
表示换行符:
bash
nl regular_express.txt | sed '2a test\ntest'
行内容替换
将 2-5 行的内容替换为 No 2-5 number
,c 为替换内容选项:
bash
nl regular_express.txt | sed '2,5c No 2-5 number'
输出指定行
输出 regular_express.txt 的第 5-7 行,其中 -n
为安静模式选项,我们在前面的章节中已经介绍过。
执行以下两条命令可以明显看出区别:
bash
nl regular_express.txt |sed -n '5,7p'
nl regular_express.txt |sed '5,7p'
字符串替换
格式为:sed 's/lodstr/newstr/g'
来看一个实例。首先查看本机 IP 地址:
bash
ifconfig eth0
字段inet 地址:192.168.x.x 即为本机的 IP 地址,这是经由 NAT 转换后分配的内网 IP 地址,在此不做展开。若想进一步学习计算机网络的相关知识可以参阅 TCP/IP 网络协议基础入门。
之后使用 grep
指令在 ifconfig eth0
的结果中查找 inet
,并打印至终端:
bash
ifconfig eth0 | grep 'inet'
可以使用字符串替换功能将 IP 前面的部分予以删除,按照思路,也就是将 inet 地址: 替换为空字符串,可以简单写成:
bash
ifconfig eth0 | grep 'inet '| sed 's/inet 地址://g'
(注意中文字符不能直接复制,需要自己在终端输入)
但正则表达式在实际应用中可以非常灵活,回想一下我们在前两节所学的关于正则表达式的知识(忘了也不要紧,可以随时返回查看)。
.
表示任意一个字符,*
表示重复字符,{ }
表示限定连续字符范围,所以正则表达式也可以写成:
bash
ifconfig eth0 |grep 'inet '| sed 's/.inet...://g'
# 或者
ifconfig eth0 |grep 'inet '| sed 's/.\{0,9\}://'
表达式的写法并不唯一,在此也并未全部列出,大家亦可自行尝试使用其他写法,欢迎在评论区中讨论。
将 IP 后面的部分删除:
bash
/sbin/ifconfig eth0 |grep 'inet '| sed 's/.inet...://g'| sed 's/..:.*$//g'
/sbin/ifconfig eth0 |grep 'inet '| sed 's/.inet...://g'| sed 's/.\{0,3\}:.*$//g'
上述指令是比较复杂的正则表达式运用,熟悉正则表达式后可以明显地简化指令,简单便捷地完成文件的查询、修改等任务。