首页 > 代码库 > sed和awk之sed篇(含sed高级用法)

sed和awk之sed篇(含sed高级用法)

(原创文章,谢绝转载~)

sed(stream editor)和 awk 是linux环境下处理文本、数据的强大“利器”,sed对数据列的处理稍逊,awk则更似一门语言,control flow的语法基本和c语言一样,能够处理复杂的逻辑,二者经常配合正则表达式使用。本文简述sed用法。

sed对输入流(文本数据)逐行处理,其基本格式为:

sed (OPTIONS...)  [SCRIPT] [INPUTFILE...]
#examples
sed ‘10d‘ test.txt
sed -i ‘s/a/b/‘ test.txt

options 有常用的:-n(消除自动打印),-i (edited in-place),-e(--expression=script),-f (--file=script-file),--help 等。

sed的script部分的格式为:

(addr)X(options)

其中addr(address)部分我们可以指定处理某些行,若无指定,则sed将处理数据流中的所有行。

X为 sed 的命令,(options) 对某些sed 命令使用,sed 的常用命令有:d(删除),p(打印),l(unambiguous打印),s(替换),i(插入文本)等等。

其中替换是最为常用的命令之一,它的格式为:

s/regexp/replacement/(flags)
#examples
sed ‘s/string/repalce/‘ test.txt
sed ‘s/^start_this/repalce/g‘ test.txt

其中g是最常用的flags,它的作用是替换所有匹配到的正则式,而非第一个(不加g时)。

sed 亦可以使用多条命令:

sed ‘1d
2d
3d‘

sed -e 1d -e 2d -e 3d

sed ‘1d;2d;3d‘

如上有多种方式执行多条命令,但需注意,用分号将命令隔开不适用于某些特殊的命令(a,c,i等),因为这些命令会将分号也视为文本而不是命令间的间隔。

接下来将说下 addr的用法,即指定行,指定行的方法有如下:

#单个数字指定,例如打印第2行
sed -n ‘2p‘
#fisrt~step,例如如下打印1,4,7,10,,,行(step为公差)
sed -n ‘1~3p‘
#正则筛选,例如如下打印end结尾行
sed -n ‘/end$/p‘  
#范围(闭区间),范围间用逗号分隔,如下为打印2到8行
sed -n ‘2,8p‘
#范围配合正则使用,如下为打印2到匹配到正则那行
sed -n ‘2,/regexp/p‘

sed的正则表达式不赘述,和一般正则差异不大,稍有syntax调整,且regexp1\|regexp2 时也是从左至右优先。

下面说下sed的高级用法:

首先需要理解下sed的运行机制,sed具有两个数据缓存区,一个所谓pattern区,一个所谓hold区,一行数据过来在pattern区执行sed处理命令,然后默认输出pattern区的内容(除非 -n 消除自动打印),然后会清空pattern区(默认),进行下一行数据操作(下一次循环)。hold区可以在循环间保持住本区数据不删除,sed的一些命令可以在pattern区和hold区之间move data。

D: 删除pattern区数据直到第一个newline, 重启循环(此时不会清空pattern区数据)

G: 将hold区数据加到pattern区, 加之前加上newline(\n)

H: 将pattern区数据加到hold区,加之前加上newline(\n)

N: 输入流再加一行到pattern区,加之前加上newline(\n)

P: 打印pattern区数据,直到第一个newline(\n)

h: pattern区的数据替换hold区的数据

看具体例子:

guest@ubuntu:~$ seq 5 |sed -n ‘N;l;D‘
1\n2$
2\n3$
3\n4$
4\n5$

N加上了\n和第二行2,于是打印出  1\n2$ ,再D删除掉 1和\n,pattern区于是剩下 2 

如此继续,N加上了\n和第三行3,于是打印出  2\n3$ ,再D删除2和\n,pattern区剩下3。后面如前所述。

再如例子:文本按行倒序打印:

guest@ubuntu:~$ seq 5 |sed -n ‘1!G;$p;h‘
5
4
3
2
1

第一行数据不执行G操作,不打印($p只打印最后一行输入),进入hold区(h操作),此时hold区数据为1

第二行数据2进入,将hold区数据1加入pattern区(G功能),此时pattern区为  2\n1,再转到hold区,此时hold区数据为 2\n1

第三行数据3进入,再将hold区 2\n1加入pattern区(G功能),此时pattern区为 3\n2\n1,再转到hold区,此时hold区数据为3\n2\n1

如此,最后一行结束时,打印出pattern区数据为上图倒序所示。

未完待续,后续将总结另一利器awk的处理数据列方面的用法~

sed和awk之sed篇(含sed高级用法)