编写sed脚本-阿里云开发者社区

开发者社区> 开发与运维> 正文
登录阅读全文

编写sed脚本

简介:

sed命令

在脚本中应用命令:

替换命令

 s/pig/cow/g

 s/cow/horse/g

模式空间

sed维护一种模式空间,即一个工作区或者临时缓冲区,当应用编辑命令时,将在那里存储单个输入行。

注意:一次一行的设计的一个优点是sed在读取非常大的文件时不会出现问题。屏幕编辑程序必须将整个文件读入内存,这将会产生内存溢出或者在处理庞大的文件时速度非常慢。

寻址上的全局透视

sed是隐式全局的,例如下面的替换命令,将每个"CA"替换成"California"

s/CA/Californai/g

我们也可以限制只对包含"Sebastopol"的行才将"CA"替换为"California"

Sebastopol/s/CA/California/g

由“Sebastopol”“CA”组成的输入行将匹配这个地址,并且应用替换命令将他替换为“Sebastopol”“California”. 右“San Fracicso”“CA”组成的行不会被匹配,而且不会应用替换命令。

sed命令可以指定零个、一个或两个地址。每个地址都是一个描述模式。行号或者行寻址符号的正则表达式。

注意:

1、如果没有指定地址,那么命令将应用于每一行。

2、如果只有一个地址,那么命令应用于与这个地址匹配的任意行。

3、如果指定了由逗号分隔的两个地址,那么命令应用于匹配第一个地址的第一行,和他后面的行,直到匹配第二个地址的行。

4、如果地址后面跟有感叹号(!),那么命令就应用于不匹配该地址的所有行。


删除命令d
1.一个只有d命令组成,并且没有地址的脚本不会产生输出,因为它删除了所有的行。
2.当行号作为一个地址提供时,命令只影响那一行,例如:1d ,删除最后一行,使用$d
3.当正则表达式作为地址提供时,这个命令只影响与这个模式匹配的行。正则表达式必须封闭在(/)中,下面的删除命令为"/^$/d" :只删除空行。
4.如果提供了两个地址,那么就指定了命令执行的行范围。下面展示了如何删除由一对宏包围的所有行,在这种情况下,.TS和.TE标记了tb1的输入:/^\.TS/,/^.TE/d 

      注意:它删除了从第一种模式匹配的行开始,到由第二种模式匹配的行(包括此行在内)为止的所有的行这个范围的行不受影响。

5.下面的命令删除了文件中从行50到最后一行的所有行:50,$d

可以混合使用行地址和模式地址:1,/^$/d 这个示例删除了从第一行直到第一个空行的所有的行,例如,可以用他来删除保存在文件中的Internet邮件消息中的邮件头。

注意:1.可以把第一个地址看做是启用地址,并把第二个地址看成是禁用动作,sed没有办法先行决定第二个地址是否会匹配。一旦匹配了第一个地址,这个动作就将应用于这些行。于是命令应用于“所有”随后的行,直到第二个地址被匹配。,在上例中,如果文件不包含空行,那么将删除所有的行。

2.跟在地址后面的感叹号会反转匹配的意义。例如,下面的脚本将删除在tb1输入块中的那些行以外的所有行。/^\.TS/,/^.TE/!d

命令分组

1.sed使用大括号({})将一个地址嵌入在另一个地址中,或者在相同的地址上应用多个命令。如果想指定行的范围,然后在这个范围内指定另一个地址,则可以嵌套地址。例如:为了只删除tb1输入块中的空行,使用下面的命令:/^\.TS/,/^\.TE/{

/^$/d

}

注意:左大括号必须在行末,而且右大括号本身必须单独占一行,并且确保在大括号之后没有空格。

2.可以使用大括号将编辑命令括起来对某个范围的行应用多个命令,如下所示:

/^\.TS/,/^\.TE/{

/^$/d

s/^\.ps 10/.ps 8/

s/^\.vs 12/.vs 10/

}

注意:这个示例不仅删除了tb1输入块中的空行,而且他还使用了替换命令s,改变了几个troff的请求,这些命令只应用于.TS/.TE块中的行。


测试并保存输出

在前面关于模式空间的讨论中,可以看到sed:

  1. 生成输入行的备份

  2. 修改模式空间中的备份

  3. 将备份输出到标准输出

这些都意味着sed有其内置的安全措施,所以会改变原始的文件。因此,下面的命令行:

sed -f sedscr testfile:不会在testfile中做改动。它将所有的行送往标准输出(一般指屏幕),----包括被修改的行和没有被修改的行。如果想要保存这些输出,就必须将他们输入到一个新的文件中。

sed -f sedscr testfile  > newfile 其中,重定向符号">"将来自sed的输出直接送往文件newfile中。不要将来自命令的输出重定向到输入文件,否则会改写输入文件,甚至可能在sed处理这个文件之前,并破坏你的数据。

检查newfile和testfile文件的差别:

diff testfile  newfile


sed脚本的四种类型

1.对同一文件的多重编辑:sed脚本的第一种类型示范了在一个文件中进行一系列编程工作。我们使用的第一个示例是将由字处理程序创建的文件转换为用于troff的编码文件。

下面是Horsefeathers Software 产品说明显然需要做的一个编辑工作的列表:

a.用段落宏(.LP)取代所有的空行。要求是匹配空行,但是,在查看输入文件内容时,空行是否有前导空格并不明显。当清楚空格后,它们没有前导空格,所以空行可以采用模式“^$”来匹配。(如果行上有空格,那么模式写成“^[]*$*”)。因此,可以用以下的方法简单的实现:

[root@localhost sed]# cat horse.txt 
HORSEFEATHERS SOFTWARE PRODUCT BULLETIN DESCRIPTION
+ _______________
BigOne Computer offers three software packages from the suite of Horsefeather software products -- Horsefeathers Business BASIC Librarian, and LIDO.  These software products can fill your 

requirements for powerful ,sophisticated,        general-purpose business software providing you with a base for software customization or development.
Horsefeathers BASIC is BASIC optimized for use on the BigOne machine with UNIX or MS-DOS operating systems. BASIC Librarian is a full screen program editor, which also provides the ability

[root@localhost sed]# sed 's/^$/.LP/' horse.txt 
HORSEFEATHERS SOFTWARE PRODUCT BULLETIN DESCRIPTION
+ _______________
BigOne Computer offers three software packages from the suite of Horsefeather software products -- Horsefeathers Business BASIC Librarian, and LIDO.  These software products can fill your 
.LP
requirements for powerful ,sophisticated,        general-purpose business software providing you with a base for software customization or development.
Horsefeathers BASIC is BASIC optimized for use on the BigOne machine with UNIX or MS-DOS operating systems. BASIC Librarian is a full screen program editor, which also provides the ability 

's/^$/.LP/' 注意:用'.LP'来取代每个空行。在替换命令的替换部分不必转义字母句点。


b.我们的第二个编辑操作是删除以"+"开始并且包含行式打印机下划线的行。此处可以用删除命令d只删除这一行。在编写匹配这一行的模式中,我们可以有许多中不同的选择,如下的多种形式都可以匹配这一行。

/^+/

/^+[空格]/

/^+[空格][空格]*/

/^+[空格][空格]*—*/

可以看出,每个正则表达式一次匹配的字符越来越多。只有通过测试才能决定需要多复杂的表达式来匹配特定的行而不是其他的行。在正则表达式中定义的模式越长,就越容易使他不会产生不想要的匹配。so,我们选择了第三种表达式:

[root@localhost sed]# sed '/^+  */d' horse.txt 
HORSEFEATHERS SOFTWARE PRODUCT BULLETIN DESCRIPTION
BigOne Computer offers three software packages from the suite of Horsefeather software products -- Horsefeathers Business BASIC Librarian, and LIDO.  These software products can fill your 

requirements for powerful ,sophisticated,        general-purpose business software providing you with a base for software customization or development.
Horsefeathers BASIC is BASIC optimized for use on the BigOne machine with UNIX or MS-DOS operating systems. BASIC Librarian is a full screen program editor, which also provides the ability
 

/^+[空格][空格]*/ 

注意:这个命令删除以加号开始并且后面跟有至少一个空格的任意行。模式中指定两个空格。但是第二个可能每个 由“*”号修饰,意味着第二个空格可以有也可以没有。

c.删除在行开始位置填充的空格。匹配序列的模式如下:

s/^[空格][空格]*// 

注意:这个命令删除在行的开头发现的任意空格序列。替换命令的替换部分为空,这意味着删除了被匹配的字符串。

eg:

[root@localhost sed]# sed 's/^  *//' horse.txt 
HORSEFEATHERS SOFTWARE PRODUCT BULLETIN DESCRIPTION
+ _______________

BigOne Computer offers three software packages from the suite of Horsefeather software products -- Horsefeathers Business BASIC Librarian, and LIDO.  These software products can fill your 

requirements for powerful ,sophisticated,general-purpose business software providing you with a base for software customization or development.Horsefeathers BASIC is BASIC optimized for use 
on the BigOne machine with UNIX or MS-DOS operating systems. BASIC Librarian is a full screen program editor, which also provides the ability 

d.处理为了对齐而添加的额外空格。我们可以编写一个替换命令匹配任意连续空格字符串并用一个空格取代他。

s/ [空格][空格] */[空格]/g 

注意:在命令的结尾添加全局标志以便取代所有的出现(不只是第一个),注意,和前面的正则表达式一样,我们不能指定有多少空格,可能有一个或者多个,不管有多少,都将他们缩减为一个空格。

友情提示:这个命令还匹配单个空格。但是因为替换的命令也是一个空格,因此有一种情况是实际上“没有工作”。

命令测试:

[root@localhost sed]# sed -e 's/  */ /g'  horse.txt 
HORSEFEATHERS SOFTWARE PRODUCT BULLETIN DESCRIPTION
+ _______________

 BigOne Computer offers three software packages from the suite of Horsefeather software products -- Horsefeathers Business BASIC Librarian, and LIDO. These software products can fill your 

requirements for powerful ,sophisticated,general-purpose business software providing you with a base for software customization or development.Horsefeathers BASIC is BASIC optimized for use 
 on the BigOne machine with UNIX or MS-DOS operating systems. BASIC Librarian is a full screen program editor, which also provides the ability 

上述的表达式有弊端。因为该表达式删除了跟在句点后的两个空格序列,而在这里本应该有两个空格。

so,为了完善替换命令以便他不会替换掉句点后面的空格,问题时句点后面也可能跟有3个空格,则需要将他们删除为2个空格。因此,表达式如下:

s/\.[空格][空格]*/.[空格][空格]/g  此命令可以简化为: s/\.[空格]/[空格][空格]/g

注意:这个命令用后面跟有两个空格的句点,替换了后面跟有任意空格的句点。


总结:

s/^$/.LP/

/^+[空格][空格]*/d

s/^[空格]*//

s/[空格][空格]*/[空格]/g

s/\.[空格][空格]*/.[空格][空格]/g


提取宏定义

       troff宏在宏包中进行定义,它通常是存放在某个目录(例如:/usr/lib/macros)下的一个文件中。troff宏定义总是以字符串'.de'开始,后面跟有可选的空格或者是由一个或者两个字母构成的宏的名字。宏定义在两个句点(..)开始的行处结束。本节的内容是从一个宏包中提取特殊的宏定义(它可以节省你用编辑器定位并且打开文件和搜索想要检查的行的时间)。

    设计此脚本的第一步是:编写提取指定宏的部分。

eg:[root@localhost sed]# sed -n '/^\.deBL/','/^\.\.$/p' /usr/lib/macros/mmt

解释:可以用-n选项来调用sed从而阻止他打印整个文件,使用这个选项,sed只打印通过打印命令显示指定要打印的行。sed脚本包含两个地址:第一个匹配宏定义的开始'.deBL',第二个匹配它的终端,"..",(它自成一行).注意:这两个模式中出现的句点用反斜杠转义。并且这两个地址指定了打印命令p的行范围,这就是搜索脚本与grep(不能匹配行的范围)功能的区别。


在shell脚本中可以使用位置符号来指定命令行上的每个参数:第一个参数是$1,第二个参数是$2.以此类推。

sed -n "/^\.de$1/,/^\.\.$/p" /usr/lib/macros/mmt注意:括住sed脚本的双引号是必须的。如果使用单引号,则shell不对“$1”进行解释。

例子:此脚本可以处理任意个宏包,下面的getmac版本允许用户将宏包的名字指定为第二个命令行参数。

[root@localhost sed]# cat getmac
#!/bin/bash

#getmac - read macro definition for $1 from package $2

file=/usr/lib/macros/mmt
mac="$1"
case $2 in 
-ms) file="/work/macros/current/tmac.s";;
-mm) file="/usr/lib/macros/mmt";;
-man) file="/usr/lib/macros/an";;
esac
sed -n "/^\.de  *$mac/,/^\.\.$/p" $file

解释:这里的新内容是case语句,它用于测试$2的值并随后给变量file赋一个值。注意:首先给file赋了一个默认的值。所以如果用户没有指定宏包,那么就会搜索-mm宏包。而且,为了清楚,易懂,$1的值被赋值给了mac。

/^\.de  *$mac/:“.de”和宏的名字之间指定了一个空格,后面跟有一个星号,这意味着这个空格是可选的。


生成提纲

文档例子:

[root@localhost sed]# cat outline.txt 
A. Shell Programming
B. Stored Commands
B. Passing Arguments to Shell Scripts
B. Conditional Execution
B. Discarding Used Arguments
B. Repetitive Execution
B. Setting Default Values
B. What We've Accomplished

此脚本需要匹配以下面的宏开始的行

** 章标题(.Se)

** 节标题(.Ah)

** 子节标题(.Bh)

如果我们需要在那些行上进行替换,用文本标记(例如:A、B)取代宏并添加适当数量的空格(使用制表符)来缩进每个标题。(记住:"."表示一个制表符)。

s/ "//g         s/[{}]//g

指定全局标志g来捕获一行上的所有出现是必要的。然而,关键是将这个脚本放在脚本的什么位置。如果我们将他放在脚本的结尾,那么它将在输出行之后删除引号。我们必须将他放在脚本的起始位置并针对多有的行进行修改,不管他们之后是否在脚本中输出。


编辑工作转移

sed作为真正的流程编辑器,在管道中进行编辑操作,这些编辑操作永远不会被写回到文件中。

下面的命令时将两个连续的破折号转为一个长破折号。

s/--/\\(em/g

我们在替换字符中用两个反斜杠来表示\(em。因为反斜杠在sed中有特殊的含义。


/---/!s/--/\(em/g        /---/!s/--/\(em/g  file | troff

解释:如果找到含有3个连续的连字符的行,不应用此编辑操作。在所有的其他行上,应用替换命令。后一个表达式的意思是:改变了输入文件并且将输出直接传递到troff,而不用创建一个中间文件。

当一个文档排版时,将连字符换成长破折号不是唯一要做的美化工作。在troff中,可以通过键入两个连续的重音符或者“反引号('')”来表示左引号。键入两个连续的单引号('')来标识右引号。我们可以使用sed将每个双引号字符换成一个单个的左引号或者单个的有引号。也就是说,当排版时,产生合适的“双引号”。










本文转自 妙曼  51CTO博客,原文链接:http://blog.51cto.com/yanruohan/1902746,如需转载请自行联系原作者

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

分享: