sed在处理文件的时候,每一行都需要存放在一个叫“模式空间”的临时缓存区!每处理完一行,便清理一次(pattern space),并把下一行再次放入!
而保留空间(hole space),是当sed用到h命令的时候,把匹配的模式放在一个叫做"hold buffer"的保留缓冲里,但需要使用G(sed的取得命令)的时候,sed 从这个保留空间(hold space)中取得(G),....
1.在脚本中应用命令
Sed首先将整个编辑脚本应用与第一个输入行,然后再读取第二个输入行并对其应用整个脚本。例:
pig1 pig2 cow3 cow4 pig5 pig6 cow7 cow8 $ sed 's/pig/cow/g ; s/cow/horse/g' test horse1 horse2 horse3 horse4 horse5 horse6 horse7 horse8
2.sed命令的语法
[address]command
[line-address]command
address{
command1
command2
command3
}
注:第一个命令可以与左大括号放置在同一行,但是右大括号必须自己单独处于一行。
在命令后添加空格会产生一个小的语法错误,这是不允许的,命令的结束必须在行的结尾处。在命令前面放置空格是可以的。
如果命令之间用一个分号分隔,那么可以将多个sed命令放在同一行。
更改、插入和追加命令必须在多行上指定,不能在同一行上指定。
3.注释
注释行的第一个字必须是“#”号。如果有必要,可以用反斜杠來结束前面的行使得注释可以继续多行。为了前后一致,必须用#开始继续行,以便使行的目的显而易见。
4.替换
[address]s/pattern/replacement/flags
这里修饰替换的标志flags是:
n:1到512之间的一个数字,表示对文本模式中指定模式第n次出现的情况进行替换
g:对模式空间的所有出现的情况进行全局更改。而没有g是通常只有第一次出现的情况被取代。
p:打印模式空间的内容。
W file:将模式空间的内容写道文件file中。
替换命令应用于与address匹配的行。如果没有指定地址,那么就应用于Pattern匹配的所有行。
和地址不同的是,地址需要一个作为定界符的斜杠(/),而正则表达式可以用任意字符來分隔,只有换行符除外。如:
s!/usr/mail!/usr2/mail!
Replacement是一个字符串,用來替换与正则表达式匹配的内容。在replacement部分,只用下列字符有特殊含义:
&:用正则表达式匹配的内容进行替换。“与“符号(&)表示模式匹配的范围,不是匹配的行。
\n:匹配第n个字串(n是1到9的一个数字),这个字串以前在pattern中用“\(”和“\)”指定。
\:当在替换部分半酣“与“符号(&),反斜杠(\)和替换命令的定界符时可以用\转义它们。另外,它用于转义换行符并创建多行replacement字符串。
Flag可以组合使用。打印标志和写标志与打印命令和写命令的功能相同,但有一个重要的区别。这些操作是随替换的成功而发生的。另外,如果脚本包含匹配同一行的多个替换命令,那么那一行的多个备份就会被打印或写到文件中。
5.删除
删除命令是一个可以改变脚本中控制流的命令。这是因为一旦执行这个命令,那么在“空的“模式空间中就不会在有命令执行。删除命令会导致读取新输入行,而编辑脚本则从头开始新的一轮(这一行为和next命令的行为相同)。
如果某行匹配这个地址,那么就删除整行,而不只是删除行中匹配的部分。
6.追加、插入和更改
语法如下:
追加[line-address]a\
text
插入[line-address]i\
text
更改[address]c\
text
插入命令是将所提供的文本放置贼模式空间的当前行之前。追加命令将文本放置在当前行之后。更改命令用所提供的文本取代模式空间的内容。
这写命令中的每一个都要求后面跟一个反斜杠用于转义第一个行尾。text必须从下一行开始。
追加命令和插入命令只应用于单个行地址,而不是一个范围内的行。而更改命令可以处理一个范围内的行。在这种情况下,它用一个文本备份取代所有被寻址的行。注意:当更改命令作为一组命令之一被封闭在大括号中并作用于一个范围内的行时,它将具有相反的功能。
插入命令和追加命令不影响模式空间的内容。提供的文本将不匹配脚本中后续命令中的任何地址,那些命令也不影响该文本。
7.列表
- 列表命令(l)用于显示模式空间的内容,将非打印的字符显示为两个数字的ASCII代码。
8.转换
- 转换命令按位置将字符串abc中的每个字符,都转换成字符串xyz中的等价字符。语法如下:
[address]y/abc/xyz/
替换根据字符的位置來进行。因此,它没有“词“的概念。这样,在该行上的任何地方的“a“都被换成了“x“,而不管它后面是否跟有“b“。
这个个命令影响整个模式空间的所有内容。
9.打印
- 打印命令(p)输出模式空间的内容。例:
/^\.Ah/{ p s/ "//g s/^\.Ah //p }
注意,打印标志被提供给替换命令。替换命令的打印标志不同于打印命令,因为它是以成功的替换为条件。
10.打印行号
- 跟在地址后面的等号(=)打印被匹配的行的行号。除非抑制行的自动输出,行号和行本身将被打印。它的语法如下:
[line-address]=
这个命令不能对一个范围内的行进行操作。
11.下一步
- 下一步(next)命令(n)输出模式空间的内容,然后读取输入的下一行,而不用返回到脚本的顶端。它的语法如下:
[address]n
12.读和写文件
- 读(r)和写(w)命令用于直接处理文件。这两个命令都只有一个参数,即文件名。语法如下:
[line-address]r file [address]w file
读命令将由file指定的文件确定的行之后的内容读入模式空间。它不能对一个范围内的行进行操作。写命令将模式空间的内容写到file中。
13.退出
- 退出命令(q)会使sed停止读取新的输入行(并停止将它们发送到输出)。它的语法为:
line-address]q
它值适用于单行地址。一旦找到和address匹配的行,那么脚本就结束。
quit的另一个可能的用法是在从文件中提取了想要的内容后退出脚本。
第六章高级sed命令
1.高级命令分成了3组:
- 处理了多行模式空间(N、D、P)。
- 采用保持空间來保存模式空间的内容并使它可用于后续的命令(H、h、G、g、x)。
- 编写使用分支和条件指令的脚本來更改控制流(:、b、t)。
2.追加下一行
- 多行Next(N)命令通过读取新的输入行,并将它添加到模式空间的现有内容之后來创建多行模式空间。Next命令将另一个新行读入模式空间。
3.多行删除
- 删除命令(d)删除模式空间的内容并导致读入新的输入行,从而在脚本的顶端重新使用编辑方法。
- 删除命令(D)稍微有些不同:它删除模式空间中知道第一个嵌入的换行符(嵌入的换行符是指文本中的第一个换行符,即第一个回车符前的内容)的这部分内容。它不会导致读入新的输入行,相反,它返回到脚本的顶端,将这些指令应用与模式空间剩余的内容。
4.多行打印
- 多行打印(P)输出多行模式空间的第一部分,知道第一个嵌入的换行符为止。
- Print命令经常出现在Next命令之后和Delete命令之前。这3个命令能建立一个输入/输出循环,用来维护两行的模式空间,但是一次只输出一行。这个循环的摸底是只输出模式空间的第一行,然后返回到脚本中的顶端将所有的命令应用与模式空间的第二行。没有这个循环,当执行脚本中的最后一个命令时,模式空间中的这两行都将被输出。
5.学习案例
- 正则表达式总是进行可能最长的匹配。
- 一旦进行跨越两行的替换,就打印第一行并且把它从模式空间删除。第二部分保留在模式空间中,将空值转移到脚本的顶端。
6.包含那一行
- 模式空间的内容可以复制到保持空间,而且保持空间的内容也可以复制到模式空间。(保持空间用于临时存储。单独的命令不能寻址保持空间或者更改它的内容。)
- 保持空间最常用的用途是,当改变模式空间中的原始内容时,用于保留当前输入行的副本。
- 影响模式空间的命令有:
-
命令 缩写 功能 Hold h或H 将模式空间的内容复制或追加到保持空间 Get g或G 将保持空间的内容复制或追加到模式空间 Exchange x 交换保持空间和模式空间的内容
- 这些命令中的每一条都可以利用一个地址來指定一行或行范围。同一命令的小写字母和大写字母之间的差别是,小写字母命令改写目的缓存区的内容,而大写字母命令追加缓存区的现有内容。
- H命令在保持空间的内容之后放置一个换行符,且后面跟随模式空间的内容(即使保持空间是空的,换行符也被追加到保持空间中)。G命令在模式空间的内容之后放置一个换行符,且后面跟随保持空间的内容。
7.高级的流空值命令
- 分支(b)和测试(t)命令将脚本中的控制转移到包含特殊标签的行。如果没有指定标签,则将控制转移到脚本的结尾处。分支命令用于无条件转移,测试命令用于有条件转移,它们只有当替换命令改变当前行时才会执行。
- 标签是任意不多于7个字符的序列(GNUsed允许标签为任意长度)。标签本身占据一行并一冒号开始:
:mylabel
在冒号和标签之间不允许有空格。行结尾处的空格将被认为是标签的一部分。当在分支命令或测试命令中指定标签时,在命令和标签之间允许有空格。注:不要在标签后面插入空格。