《Sed 和 Awk》(第二版)学习系列之第六章

 

第六章  高级sed命令

 

1.     高级命令主要分成3组:

(1)    处理多行模式空间(N, D, P)

(2)    采用保持空间来保存模式空间中的内容并使它可用于后续的命令(H, h, G, g, x)

(3)    编写使用分支和条件指令的脚本来更改控制流(:, b, t)

1.     多行模式空间:

(1)    追加下一行(N): 多行命令通过读取新的输入行,并将其添加到模式空间的现有内容之后来创建多行模式空间,模式空间最初的内容和新的输入行之间用换行符分割,在模式空间中嵌入的换行符可以通过转义字符\n来匹配,在多行模式空间中,元字符^匹配模式空间中的第一个字符,而不匹配换行符后面的字符,同样,$只匹配模式空间中最后的换行符,而不匹配任何嵌入的换行符,在执行Next(N)命令后,控制将被传递给脚本中的后续命令,与next(n)命令不同的是,next输出模式空间的内容,然后读取新的一行。

(2)    多行删除(D): 删除命令d删除模式空间中的内容并自动读取新的输入行,从而在脚本的顶端重新使用编辑方法,D删除命令稍微有些不同,它删除的是模式空间中直到第一个嵌入的换行符的这部分内容(可以看到,基本上D删除命令只是删除多行中的第一行),另外,它不会导致读入新的输入行,并且它返回的是脚本的顶端

【举例】

测试文件:

删除命令组:

测试结果:

【解释】首先,一定要理解“模式空间是以^符号开始,并以$符号结束的”这句话,“^\n$”实际上匹配的是两个空行。因此,原命令组的含义是先定位每个空行,然后追加每个空行的下一行,若这两个时空行,则删除之,否则,跳过。若将删除命令换成D,则结果将不同,这是因为当遇到两个空行时,则会首先删除第一个空行,并在下次遍历脚本时,将下一行进行读入,若这行是空白的,则将会继续删除,否则一起输出。这正是当有多行空格时,依然最后只保留一个空格的原因。

(3)多行打印命令(P):多行打印命令与p命令的差别在于,该命令只是输出多行模式空间的第一部分,直到第一个嵌入的换行符为止,在执行完脚本的最后一个命令后,模式空间的内容会自动输出(可以使用-n选项进行抑制),

     ♥ P命令经常出现在N之后和D之前,这三个命令可以形成一个输入/输出循环,用来维护两行的模式空间,但是一次只能输出一行,然后返回到脚本的顶端将所有的命令应用于模式空间的第二行

       ♥ 对P输出的理解可参考前面的多行删除命令D.

       ♥ 实例分析:

 测试文件:(test)

Here are examples of the UNIX

System.  Where UNIX

System appears, it should be the UNIX

Operating System.

sed脚本:(sed)

/UNIX$/{

N

/\nSystem/{

s// Operating &/

P

D

}

}

/UNIX$/{

N

s/\nSystem/ Operating &/

P

D

}

 结果及其分析:sed –f sed test

Here are examples of the UNIX Operating

System.  Where UNIX Operating

System appears, it should be the UNIX

Operating System.

     

【分析】上面的sed脚本有两个,二者是等价的,作用均是将所匹配的\nSystem替换为

Operating \nSystem, 注意前面所讲的sed中替换的replacement中的几个特殊符号所代表的含义,&则是代表前面所代表的匹配字符,即“\nSystem”;另外替换中若没指定地址,则将所匹配的pattern进行替换,在这个地方, s// Operating &/ 表示将所匹配的\nSystem进行替换。

3     包含哪一行:(H,h,G,g)

♥ 保持空间:保持空间是一个预留缓冲区,它可以与模式空间中的内容进行交换,它最常见的用途是,在

改变模式空间中的内容时,用于保留当前输入行的副本。影响模式空间的命令有:

【注意】大小写命令之间的区别是:小写命令直接改写目的缓存区的内容,而大写命令则是追加缓存

区的现有内容。Hold命令会在保持空间的内容之后放置一个换行符,然后后面跟随模式空间的内容,

尽管保持空间中的内容可能会是空的;Get命令在模式空间的内容之后放置一个换行符,然后后面跟

随保持空间的内容。交换命令则用来交换两个缓存区的内容,这对两个缓存区是没有任何副作用的。

♥ 实例分析:

  测试文件:

find the Match statement

Consult the Get statement.

using the Read statement to retrieve data

  sed脚本:

/the .* statement/{

h

s/.*the \(.*\) statement.*/\1/

y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/

G

s/\(.*\)\n\(.*the \).*\( statement.*\)/\2\1\3/

}

结果与分析:sed –f sed test

  【分析】这个脚本的主要功能是将the与statement之间的单词全部转换成大写字母,如果单纯用前面的转换命令(y),是不能实现这个功能的,因为转换命令所施作用对象是所有行,必须借助保持空间与模式空间中的缓存交换来实现。

h

pattern space: find the Match statement

hold space: find the Match statement

s/.*the \(.*\) statement.*/\1/

pattern space: Match

hold space: find the Match statement

y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/

pattern space: MATCH

hold space: find the Match statement

G(追加,另外加上换行符)

pattern space: MATCH\nfind the Match statement

hold space: find the Match statement

s/\(.*\)\n\(.*the \).*\( statement.*\)/\2\1\3/

pattern space: find the MATCH statement

hold space: find the Match statement

上面是所匹配的第一行经历脚本之后,模式空间和保持空间中剩余的内容,在此需要解释的是:

替换命令中的\n所代表的含义,它是用来匹配第n个字串,这个字串之前在pattern中用\(和\)指定,因此这个命令类似于“抓取”的功能,只是把整行中某一部分抽取出来。另外注意在书写脚本时,不要忘记字符之间隐藏的空格。

4.    高级的流控制命令:分支(b),测试(t)

(1) 分支和测试命令将脚本中的控制转移到指定的标签行。若没有指定标签,则将控制转移到脚本的结尾

处,其中分支命令是无条件转移,测试命令用于有条件转移,它只有当转换命令改变时才会执行

标签是任意不多于7个字符的序列,标签本身占据一行并以冒号开始

:mylable --------------------------中间不能有空格

b mylable ---------------------------命令和标签之间有空格,但不能在标签后面再插入空格

(2) 分支命令用于在脚本中将控制权转移到另一行

[address]b[label] ----------label是可选的,若没有,则跳至脚本结尾处,否则,调至标签后面

分支命令可以用来构造选择和循环过程:

(循环)

 

 (选择,命令1和2只能选其一)

(选择,命令2和3选其一)

(3) 若在当前匹配地址的行上进行成功替换,则test命令就转到标签处,若没有,转到结尾处,实际上实现了条件功能。

5. 综合实例:

   跨行查找短语(可能中间出现断裂而出现在不同的行):

#! /bin/sh

# phrase -- search for words across lines

# $1 = search string; remaining args = filenames

search=$1

shift

for file

do

sed '

/'"$search"'/b   --------------------第一行出现匹配短语,直接退出并打印

N

h

s/.*\n//   -----------------------只保留第二行,并将前两行存放到保持空间

/'"$search"'/b  ----------------第二行出现匹配短语,直接退出打印

g

s/  *\n/  /   -----------------------将前两行组成一个整体,为后面的检测做准备

/'"$search"'/{

g

b

}   ----------------------------------若整体行出现匹配短语,则将两行同时打印出来

g

D' $file   -------------------------------防止出现跨行匹配,删除第一行,保留第二行,控制转移到顶端

done

【注意】这个脚本有个缺陷,总会打印出源test文本中最后一行字符串!

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
sedawk是用户、程序员和管理员应用的工具。之所以称为sed是因为它是一个流编辑器(stream editor),用于对许多文件执行一系列的编辑操作。awk是根据它的开发者Aho、Weinberger和Kernighan命名的。awk是一种编程语言,它可以使你很容易地处理结构化数据和生成格式化报告。第二版介绍了awk的POSIX标准,同时介绍了一些可免费使用的以及商业版的awk。 本书在一开始就给出了一个概述和指南,论述了从grep到sed再到awk不断改进的功能。sedawk具有相同的命令行语法,以脚本的形式接收用户的命令。因为所有这三个程序都使用UNIX正则表达式,因此书中用一章的篇幅来介绍UNIX的正则表达式语法。 然后,本书介绍如何编写sed脚本。从编写几行简单的脚本开始,学习进行手工编辑操作的其他基本命令和高级命令,以及由此引入的简单程序结构。这些高级命令包括用于处理保持空间、即一个临时缓冲区的命令。 本书的第二部分经过广泛的修订,包括了POSIX awk,以及3个可免费使用的和3个商业版的awk。本书介绍了awk语言的主要特点以及如何编写简单的脚本。你还能了解到: * 通用的程序结构 * 如何使用awk的内部函数 * 如何编写用户的定义函数 * awk程序的调试技术 * 如何开发一个处理索引的应用程序,该程序演示了awk的强大功能 * 得到不同awk版本的FTP和联系信息 本书还包含了一组用户提供的程序,这些程序展示了广泛的sedawk程序风格和技巧。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值