通过几个例子看sed的模式空间和保持空间 例子一 sed G 在文档每一行下面输出一个空行 代码: $ cat foo 11111111111111 22222222222222 33333333333333 44444444444444 55555555555555 $ sed G foo 11111111111111
22222222222222
33333333333333
44444444444444
55555555555555
解释:sed 中 G 的用法 The G function appends the contents of the holding area to the contents of the pattern space. The former and new contents are separated by a newline. The maximum number of addresses is two. hold space : 保持空间(或叫保留空间、缓冲区),初始为空 pattern space :模式空间 在上面的例子中,将为空的hold space附加到文档的每一行后面,所以结果是每一行后面多了一个空行 引申出: sed '/^$/d;G' 在文档的每一个非空行下面输出一个空行 sed '/^$/d;G;G' 在文档的每一个非空行下面输出两个空行 代码: $ cat foo 11111111111111 22222222222222 33333333333333 44444444444444 55555555555555 $ sed '/^$/d;G' foo 11111111111111
22222222222222
33333333333333
44444444444444
55555555555555 注:有时会有一些由空格符或TAB组成的空行,前面的正则式 ^$ 就不能匹配到这样的行,则能够这样 sed '/[[:space:]]/d;G' 对于KSH则为 sed '/^ *$/d'
例子二 sed '/regex/{x;p;x;}' 在匹配regex的任何行前面插入一个空行 代码: $ cat foo 11111111111111 22222222222222 test33333333333 44444444444444 55555555555555
$ sed '/test/{x;p;x;}' foo 11111111111111 22222222222222
test33333333333 44444444444444 55555555555555 解释:sed 中 x 的用法 The exchange function interchanges the contents of the pattern space and the holding area. The maximum number of addresses is two. 即交换保持空间hold space和模式空间pattern space的内容 sed 中 p 的作用是把模式空间复制到标准输出。 分析一下该命令执行过程中保持空间和模式空间的内容 命令 保持空间 (holdspace) 模式空间(patternspace) x 执行前:null 执行后:test...$ 执行前:test...$ 执行后:null p 执行前:null 执行后:test...$ 执行前:test...$ 执行后:null 输出一个空行 x 执行前:test...$ 执行后:null 执行前:null 执行后:test...$ 个人觉得上面的命令执行分析有点问题,我的分析如下: 命令 模式空间(patternspace) 保持空间 (holdspace) x 执行前:test...$ 执行后:null 执行前:null 执行后:test...$ p 执行前:null 执行后:null但输出一空行 执行前:test...$ 执行后:test...$ x 执行前:null 执行后:test...$ 执行前:test...$ 执行后:null 引申:能够试验一下 sed '/test/{x;p;}' foo 或 sed '/test/{p;x;}' foo 等,看看结果,体会两个空间的变化
相应的: sed '/regex/G' 是在匹配regex的任何行下面输出一个空行 sed '/regex/{x;p;x;G;}' 是在匹配regex的任何行前面和下面都输出一个空行
例子三 sed 'n;G;' 在文档的偶数行下面插入一个空行 代码: $ cat foo 11111111111111 22222222222222 33333333333333 44444444444444 55555555555555 $ sed 'n;G;' foo 11111111111111 22222222222222
33333333333333 44444444444444
55555555555555 解释:sed 中 n 的用法:将模式空间拷贝于标准输出。用输入的下一行替换模式空间。 ==::执行n 以后将第一行输出到标准输出以后,然后第二行进入模式空间,根据前面对G的解释,会在第二行后面插入一个空行,然后输出;再执行n 将第三行输出到标准输出,然后第四行进入模式空间,并插入空行,依此类推.... 相应的: sed 'n;n;G' 表示在文档的第 3,6,9,12,... 行后面插入一个空行 sed 'n;n;n;G' 表示在文档的第 4,8,12,16,... 行后面插入一个空行 sed 'n;d' 表示删除文档的偶数行
例子四 sed '$!N;$!D' 输出文档最后2行,相当于 tail -2 foo 代码: $ cat foo 11111111111111 22222222222222 33333333333333 44444444444444 55555555555555 $ sed '$!N;$!D' foo 44444444444444 55555555555555 解释: D 删除模式空间内第一个newline 字母/n 前的资料。 N 把输入的下一行添加到模式空间中。 sed '$!N;$!D' : 对文档倒数第二行以前的行来说,N 将当前行的下一行放到模式空间中以后,D 就将模式空间的内容删除了(补充一点:D是将模式空间的的第一行删除);(循环删除到模式空间里只剩下倒数第二行时)到倒数第二行的时候,将最后一行附加到倒数第二行下面,然后最后一行不执行 D ,所以文档的最后两行都保存下来了。 更有 N 的另外一种用法代码: $ sed = foo | sed N (一定要这样的命令格式) 1 11111111111111 2 22222222222222 3 33333333333333 4 44444444444444 5 55555555555555 $ sed = foo | sed 'N;s//n/ /' 1 11111111111111 2 22222222222222 3 33333333333333 4 44444444444444 5 55555555555555 解释:N 的作用是加上行号,能够用于格式化输出文档
例子五 sed '1!G;h;$!d' sed -n '1!G;h;$p' 将文档的行反序显示,相当于 tac 命令(有些平台没有这个命令) 代码: $ cat foo 11111111111111 22222222222222 33333333333333 $ sed '1!G;h;$!d' foo 33333333333333 22222222222222 11111111111111 $ sed -n '1!G;h;$p' foo 33333333333333 22222222222222 11111111111111 解释:sed 中 h 用法:h The h (hold) function copies the contents of the pattern space into a holding area, destroying any previous contents of the holding area. 意思是将模式空间的内容保存到保持空间中去 sed 中的 d 表示删除模式空间。 1!G表示除了第一行以外,其余行都执行G命令;$!d表示除了最后一行以外,其余行都执行d命令。 看一下sed '1!G;h;$!d'命令执行过程中保持空间和模式空间的变化: 命令 保持空间 模式空间 第一行 h;d 执行前:null 执行后:11..$ 执行前:11..$ 执行后:null 第二行 G;h;d 执行前:11..$ 执行后:22..$/n11..$ 执行前:22..$ 执行后:null 第二行 G;h 执行前:22..$/n11..$执行后:33..$/n22..$/n11..$ 执行前:33..$ 执行后:33..$/n22..$/n11..$ 这样输出以后就是文档的反序了。
题外话:在vi中对一个文档进行反序显示的命令是 :g/./m0 , 意思是按照文档正常顺序每找到一行,就把该行放到文档的最上面一行去,这样循环一下正好把文档的行反序显示了。 |