简介
grep、sed、awk是处理文本的强大工具。
perl是在grep、sed、awk基础上,产生的语言。
现在,个人习惯是,文本处理用grep、sed、awk,命令胶水用perl。
不要追求编程语言的唯一化,多种语言语法类似,功能却很有特色。好处还有,程序看起来更简洁,更容易理解。
grep、sed、awk、perl对正则表达式的使用,是有区别的。这一点,要熟悉注意。参考文档:
个人基础及笔记重点
- sed/grep/awk熟悉
初级教程看:
- 不精通
- 主要是了解忽略的细节(初级用户看中文教程,完成入门–>熟悉之路)。从熟悉–>精通之路。还是突出实用,复杂的用perl脚本去实现。
- 很多话,特别是sed高级部分,都是自己理解的。如有错误,在所难免。
sed基础
sed处理大文件很方便,使用vim等编辑1M以上的文件,太慢;编辑1G以上的文件,力不从心,会崩溃。
sed高级应用,主要是熟悉模式空间。只有两个空间,1是pattern space模式空间;2是hold space保持空间。
sed正则表达式必须要熟悉。不管是sed,其它grep、awk、perl都是基于正则表达式的语言脚本。
sed命令,主要包括参数+寻址+命令+标志。如替换命令的格式,
[address]s/pattern/replacement/flags
常用参数包括:
- i,edit in place。即直接作用于文本,不会有备份,要注意。
- n,不打印非匹配的行。一般结合p命令使用,只显示特别的行。
- e,连续命令。这个参数不必要,不如直接用;隔开每个sed命令。
- 其它参数,用
sed --help
查阅
寻址包括:
- 没有寻址,命令作用于每一行。如
s/aaa/bbb/
;注意s/aaa/bbb/g
,全局替换是指的行内全局。
- 只有一个地址,命令作用于匹配的那些行。如
/ccc/s/aaa/bbb/
- 寻址用逗号分隔的,命令作用于起始到结束的行。如
1,5s/aaa/bbb/
,1~5行做替换。
- 感叹号,命令作用于不匹配的那些行。如
/ccc/!s/aaa/bbb/
常用命令包括:
因为sed起源一个行编辑器ed,所以命令一般都是单字符。结合vim里的命令去记忆理解很容易。
- 一共25个命令;
- d #删除
- a\ text #追加append
- c\ text #change
- i\ text #插入
- l #小写的L,列表命令,显示模式空间的内容(之后将模式空间)。可以显示不能输入的字符,查阅特别字符时很管用。比如日常偶尔碰到的,代码看起来完全正确,但是执行报告错误;这也许是有看不见的特殊字符导致的bug。
- [address]y/abc/ABC/ #y命令是字符转换命令,是单字符的转换。比如这个命令的意思是,a转换或者替换为A;b转换或者替换为B;c转换或者替换为C。
- p #打印命令,一般跟sed -n 配合使用。
- = #打印行号。
- n #本行跳过执行命令,直接下一行。(跟模式空间配套使用)
- [line-address]r file #读命令,只能用行号范围进行匹配。【不怎么用到】
- [address]w file #写命令。【不怎么用到】
- [line-address]q #退出命令。只对单行有意义。
标志flags
- n #1~512之间的数字,对第几个进行命令执行。
- g #全局global,进行命令执行。
- p #打印命令
- W file #写入文件
正则表达式
- ^ #表示匹配模式空间的开头。不要单纯理解为行首
- $ #表示匹配模式空间的结尾。不要单纯理解为行尾
- 注意:如果用到sed多行处理模式时,^和$就不是行首行尾的意义了。
sed高级(这一章要详细讲解,要不迷惑性太大。举例。)
sed高级命令,主要包括3个部分:
1. 多行处理模式空间(N P D),注意与(n p d)的区别!!!个人经验:多行处理时,不要用npd命令,否则理解混乱。
2. 采用保持空间hold space,用来保存模式空间的内容,并使之继续服务于后续命令。
3. 分支和条件指令(: b t)
参考文档:
熟悉–>精通之路,必需技巧工具:
利用sed调试工具sedsed
,去理解sed命令每一步执行后的效果。sedsed需要python编译器支持,而且必须是python2版本,而不是python3版本。sedsed调试命令很简单,不再赘述。
N命令
n命令,是忽略当前行的命令,直接去下一行开始命令执行。
N命令,追加下一行到模式空间的内容,而且下一行就不会执行命令
。(看来模式空间,要在sed高级章节之前讲解,否则越来越费劲)
注意:N还有另外一个特性:当无法处理下一行内容时,N则会中止退出,所以后面的命令也不会再执行。比如最后一行处理时,遇到N命令,会无法处理最后一行的其它命令。所以建议N命令,就直接使用$!N
得了($!N
,意思就是最后一行不执行N命令,其它行都执行N命令),避免不必要的debug困难。
参考文档:
下面讲讲N(我只用$!N
)命令的描述与例子:多行的处理。
执行过程如下:
$ cat sed.1
consult section 3.1 in the owner and operator
guide for a description of the tape drives
available on your system
aaaaaaaaaaaaaa owner and operator111
bbbbbbbbbbbbbbbbbbbb
$ sed '/operator$/{$!N;s/owner and operator\nguide /installation guide/}' sed.1
consult section 3.1 in the installation guidefor a description of the tape drives
available on your system
aaaaaaaaaaaaaa owner and operator111
bbbbbbbbbbbbbbbbbbbb
$ /d/python27/sedsed -d --color '/operator$/{$!N;s/owner and operator\nguide /installation guide/}' sed.1
PATT:consult section 3.1 in the owner and operator$
HOLD:$
COMM:/operator$/ {
COMM:$ !N
PATT:consult section 3.1 in the owner and operator\nguide for a descr\
iption of the tape drives$
HOLD:$
COMM:s/owner and operator\nguide /installation guide/
PATT:consult section 3.1 in the installation guidefor a description o\
f the tape drives$
HOLD:$
COMM:}
PATT:consult section 3.1 in the installation guidefor a description o\
f the tape drives$
HOLD:$
consult section 3.1 in the installation guidefor a description of the tape drives
PATT:available on your system$
HOLD:$
COMM:/operator$/ {
PATT:available on your system$
HOLD:$
available on your system
PATT:aaaaaaaaaaaaaa owner and operator111$
HOLD:$
COMM:/operator$/ {
PATT:aaaaaaaaaaaaaa owner and operator111$
HOLD:$
aaaaaaaaaaaaaa owner and operator111
PATT:bbbbbbbbbbbbbbbbbbbb$
HOLD:$
COMM:/operator$/ {
PATT:bbbbbbbbbbbbbbbbbbbb$
HOLD:$
bbbbbbbbbbbbbbbbbbbb
注意:不能用\n表示换行,可以用\回车,命令里写成两行。这样就可以输出换行符。如下命令:
$ sed '/operator$/{$!N;s/owner and operator\nguide /installation guide\
/}' sed.1
consult section 3.1 in the installation guide
for a description of the tape drives
available on your system
aaaaaaaaaaaaaa owner and operator
D命令
d命令,是删除匹配的那一行;
D命令,是多行处理模式空间的命令,是删除匹配的第一行。而且可以认为,N和D一起时,N的下一行不会执行sed命令;但是D命令会改变N这个策略,D命令会要求N的下一行也执行sed命令。
这段话理解有些困难。利用sed调试工具sedsed
,去理解sed命令的效果。
举例:多行空格删减为一行
$ cat sed.2
this line is followd by 1 blank line.
this line is followd by 2 blank line.
this line is followd by 3 blank line.
this line is followd by 4 blank line.
this is the end.
$ sed '/^$/{$!N;/^\n$/D}' sed.2
this line is followd by 1 blank line.
this line is followd by 2 blank line.
this line is followd by 3 blank line.
this line is followd by 4 blank line.
this is the end.
$ /d/python27/sedsed -d --color '/^$/{$!N;/^\n$/D}' sed.2
PATT:this line is followd by 1 blank line.$
HOLD:$
COMM:/^$/ {
PATT:this line is followd by 1 blank line.$
HOLD:$
this line is followd by 1 blank line.
PATT:$
HOLD:$
COMM:/^$/ {
COMM:$ !N
PATT:\nthis line is followd by 2 blank line.$
HOLD:$
COMM:/^\n$/ D
PATT:\nthis line is followd by 2 blank line.$
HOLD:$
COMM:}
PATT:\nthis line is followd by 2 blank line.$
HOLD:$
this line is followd by 2 blank line.
PATT:$
HOLD:$
COMM:/^$/ {
COMM:$ !N
PATT:\n$
HOLD:$
COMM:/^\n$/ D
PATT:$
HOLD:$
COMM:/^$/ {
COMM:$ !N
PATT:\nthis line is followd by 3 blank line.$
HOLD:$
COMM:/^\n$/ D
PATT:\nthis line is followd by 3 blank line.$
HOLD:$
COMM:}
PATT:\nthis line is followd by 3 blank line.$
HOLD:$
this line is followd by 3 blank line.
PATT:$
HOLD:$
COMM:/^$/ {
COMM:$ !N
PATT:\n$
HOLD:$
COMM:/^\n$/ D
PATT:$
HOLD:$
COMM:/^$/ {
COMM:$ !N
PATT:\n$
HOLD:$
COMM:/^\n$/ D
PATT:$
HOLD:$
COMM:/^$/ {
COMM:$ !N
PATT:\nthis line is followd by 4 blank line.$
HOLD:$
COMM:/^\n$/ D
PATT:\nthis line is followd by 4 blank line.$
HOLD:$
COMM:}
PATT:\nthis line is followd by 4 blank line.$
HOLD:$
this line is followd by 4 blank line.
PATT:$
HOLD:$
COMM:/^$/ {
COMM:$ !N
PATT:\n$
HOLD:$
COMM:/^\n$/ D
PATT:$
HOLD:$
COMM:/^$/ {
COMM:$ !N
PATT:\n$
HOLD:$
COMM:/^\n$/ D
PATT:$
HOLD:$
COMM:/^$/ {
COMM:$ !N
PATT:\n$
HOLD:$
COMM:/^\n$/ D
PATT:$
HOLD:$
COMM:/^$/ {
COMM:$ !N
PATT:\nthis is the end.$
HOLD:$
COMM:/^\n$/ D
PATT:\nthis is the end.$
HOLD:$
COMM:}
PATT:\nthis is the end.$
HOLD:$
this is the end.
跳转命令:a;….;ba;
不管…;命令是否执行成功,都会跳转到:a位置,然后开始执行命令。
跳转命令:a;….;ta;
判断…;命令是否执行成功,如果执行成功会跳转到:a位置,然后开始执行命令;如果执行失败不会跳转。
h/H;g/G;x利用保持空间的命令
命令很容易理解,需要做的,无非就是利用以上命令,形成一个算法。
复杂的sed命令,就用sedsed
去调试理解。
熟悉例子
SED单行脚本快速参考
http://sed.sourceforge.net/sed1line_zh-CN.html
结合sedsed调试命令,查看命令执行过程,消化理解。可以事倍功半。
最后是自己写程序,debug。
最大的感受,还是sedsed调试命令。语法学习,还是要从调试手段来加深理解。