概述
sed是一个流编辑器(Stream EDitor)。主要用于自动编辑一个或多个文件;简化对文件的反复操作;编写转换程序等。本文主要讲述了:
-
sed工作原理
-
sed命令格式及常用选项
-
应用实例
-
高级编辑命令
sed工作原理
sed命令运行过程中维护着两个缓冲区,一个是活动的“模式空间(pattern
space)”,另一个是起辅助作用的“暂存缓冲区(holding space)”。sed每次处理一行内容,整个文件像流水一样被逐行处理然后逐行输出。处理时,把当前处理的行存储在”模式空间”(pattern space ),接着用sed 命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。接着处理下一行,这样不断重复,直到文件末尾。工作过程如下图所示:
一般情况下暂存缓冲区是用不到的,但有特殊的命令可以在模式空间与暂存缓冲区之间交换数据,由于sed对文本的所有操作都是在模式空间里进行的,所以,默认情况下,sed不会对原文件内容修改,处理后的所有输出行都被打印到屏幕上,除非你使用重定向存储输出。
sed命令格式及常用选项
用法:
sed [OPTION]... PATTERN [input-file]...
OPTION:
-n:不输出模式空间中的内容至屏幕; -e script, --expression=script:多点编辑; -f /PATH/TO/SED_SCRIPT_FILE 每行一个编辑命令; -r,--regexp-extended:支持使用扩展正则表达式; -i[SUFFIX], --in-place[=SUFFIX]:直接编辑原文件 ; #一般不建议-i,如需进行文件修改,强烈建议先备份,即-i.CHAR。(.CHAR为备份文件后缀名,可自定义。)
PATTERN:
PATTERN是一组特定的sed命令(很多时候也称之SCRIPT),一定要被包含在一对单引号中,以免被shell解释,其格式如下:
'[address-range]sed-command'
address-range是指要处理的行的范围,又叫地址界定;
sed-command是一个sed命令,用来对指定的行进行处理。
地址界定:
1. 空地址:对全文进行处理; 2. 单地址: n:指定第n行; /pattern/:被此模式所匹配到的每一行; 3. 地址范围 n,m:第n行开始至第m行 n,+m:第n行开始,至后面的m行 n,/pat1/:第n行开始,至第一次匹配pat1的行 /pat1/,/pat2/:第一个匹配pat1的行开始,至第一个匹配pat2的行 $:最后一行; 4. ~步进: n~m:第n行开始,每次步进m行 1~2:所有奇数行 2~2:所有偶数行
编辑命令:
d:删除; p:显示模式空间中的内容; a \text:在行后面追加文本“text”,支持使用\n实现多行追加; i \text:在行前面插入文本“text”,支持使用\n实现多行插入; c \text:把匹配到的行替换为此处指定的文本“text”; w /PATH/TO/SOMEFILE:保存模式空间匹配到的行至指定的文件中; r /PATH/FROM/SOMEFILE:读取指定文件的内容至当前文件被模式匹配到的行后面;文件合并; =:为模式匹配到的行打印行号; !:条件取反; 地址定界!编辑命令; s///:查找替换,其分隔符可自行指定,常用的有s@@@, s###等; 替换标记: g:全局替换; w /PATH/TO/SOMEFILE:将替换成功的结果保存至指定文件中; p:显示替换成功的行; {COMMANDS}:可以把多个命令括起来,用来处理单个地址或者地址范围。 sed -n '5,9p;=' sed -n '5,9{p;=}'
高级编辑命令:
h:把模式空间中的内容覆盖至保持空间中; H:把模式空间中的内容追加至保持空间中; g:把保持空间中的内容覆盖至模式空间中; G:把保持空间中的内容追加至模式空间中; x:把模式空间中的内容与保持空间中的内容互换; n:覆盖读取匹配到的行的下一行至模式空间中; N:追加读取匹配到的行的下一行至模式空间中; d:删除模式空间中的行; D:删除多行模式空间中的所有行;
应用实例
不同的系统环境或sed版本的命令实现有可能有微改动,但是用法基本不变,下列演示基于如下环境中进行:
-
OS: CentOS Linux release 7.2.1511 (Core)
-
sed version: sed (GNU sed) 4.2.2
演示文件1:
[root@IP70-CentOS7 ~]# >>sed '2p' /etc/passwd #打印第二行
[root@IP70-CentOS7 ~]# >>sed -n '2p' /etc/passwd #仅打印第二行
[root@IP70-CentOS7 ~]# >>sed -n '1,4p' /etc/passwd #仅打印第1到第4行(范围地址)
[root@IP70-CentOS7 ~]# >>sed -n '/root/p' /etc/passwd #仅打印匹配root的行(单地址模式匹配)
[root@IP70-CentOS7 ~]# >>sed -n '2,/root/p' /etc/passwd #仅打印从第2行开始,至匹配root的行(范围地址)
[root@IP70-CentOS7 ~]# >>sed '/root/a\superman' /etc/passwd #sed-command演示:a:匹配行后追加文本
[root@IP70-CentOS7 ~]# >>sed '/root/i\superman' /etc/passwd #sed-command演示:i:匹配行前插入文本
[root@IP70-CentOS7 ~]# >>sed '/root/c\superman' /etc/passwd #sed-command演示:c:匹配行替换成指定文本
[root@IP70-CentOS7 ~]# >>sed -n 's/root/&superman/p' /etc/passwd #sed-command演示:s:查找root,替换成&superman(&代表引用匹配查找的内容)
[root@IP70-CentOS7 ~]# >>sed 's/root/superman&/g' /etc/passwd #sed-command演示:s:查找替换,对比上个示例,p仅替换每行第一个匹配的文本,g就进行全局匹配
演示文件2:
[root@IP70-CentOS7 ~]# >>sed -n '/^$/=' testfile #sed-command演示:= 显示行号(^$ 空行)
[root@IP70-CentOS7 ~]# >>sed -n -e '/^$/p' -e '/^$/=' testfile #选项 -e的引用
[root@IP70-CentOS7 ~]# >>sed '/^$/d' testfile #sed-command演示:d 删除匹配的行
[root@IP70-CentOS7 ~]# >>sed '1,10d' testfile #范围地址第1至第10行, sed-command: d删除行
[root@IP70-CentOS7 ~]# >>sed -i.bak 's/^test.*$/deleted/g' testfile #选项-i的应用,如需进行文件修改,强烈建议先备份,即-i.CHAR。(.CHAR为备份文件后缀名,可自定义。)
高级编辑命令
[root@IP70-CentOS7 ~]# >>sed -n 'n;p' testfile.bak #打印偶数行
[root@IP70-CentOS7 ~]# >>sed '1!G;h;$!d' testfile.bak #倒序显示行,相当于tac命令
[root@IP70-CentOS7 ~]# >>sed '$!N;$!d' testfile.bak
[root@IP70-CentOS7 ~]# >>sed '$!N' testfile.bak
[root@IP70-CentOS7 ~]# >>sed '$!d' testfile.bak
[root@IP70-CentOS7 ~]# >>sed 'G' testfile.bak
[root@IP70-CentOS7 ~]# >>sed 'n;d' testfile.bak
结束语
个人认为相较于grep而言,sed查找匹配行后可进行更多的命令操作,提供的d删除和s替换功能更是如虎添翼。掌握一项技能在于多用,在理解上述演示的前提下,在实际应用中纵向深挖,与人分享探讨。
由于初学Linux,限于本人水平有限,文中难免错误纰漏。欢迎各位看官不吝指教、讨论相关技术。谢谢。
联系我:jacky18676887374@aliyun.com
原创文章,作者:昭其,如若转载,请注明出处:http://www.178linux.com/32451