5.10. 四种 sed 脚本——对同一个文件的多次编辑——第一部分
5.10 四种 sed 脚本——对同一个文件的多次编辑——第一部分
第一种 sed 脚本展示了对一个文件进行一系列的编辑。例子是把被单词处理程序创建的一个文件转换为能被 troff 编程的文件。
有一个作者曾经为一个现在被称作 BigOne Computer 的电脑公司做了一个写作项目。文档必须为“胡扯软件”包含一个产品公告。公司承诺产品公告在网上,然后将发出来。不幸的是,当文件抵达时,它包含的是为行式打印机提供的格式化输出,这是它们唯一能够提供的方式。那个文件(保存在一个名为 horsefeathers 的文件中用于测试)的一部分如下。
HORSEFEATHERS SOFTWARE PRODUCT BULLETIN
DESCRIPTION
+ ___________
BigOne Computer offers three software packages from the suite
of Horsefeathers software products -- Horsefeathers Business
BASIC, 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
注意,这个文本使用了单词之间的空格来两端对齐。左边还添加了空格,用来创建一个左外边距。
当使用 sed 来解决一个问题时,如果在脑海里把要做的所有事情做一个列表,会做得最好。当开始编程时,写一个脚本,包含做一件事情的一个命令。测试它成功工作,然后添加另一个命令,重复这个循环,直到完成了所有显而易见的事情。(“所有显而易见”是因为这个列表并不总是完整的,且“实现——测试”这个循环通常添加其它的项目到这个列表里。)
这种工作方式看起来是相当枯燥的过程,并且确实有许多脚本是可以尝试一次性写完,然后开始测试。然而对初学者来说,高度推荐这种一次一步的技术。因为隔离了每一个命令,很容易地得知它是否正常工作。当一次性运行几个命令时,可能会发现当问题出现时,会重复反向进行刚才推荐的过程。也就是说一次移除一条命令,直到定位到问题。
这里是一个需要对胡扯软件公告进行编辑的列表:
- 使用一个段落宏 .LP 替换掉所有的空格行。
- 移除每一行所有的前导空格。
- 移除打印机下划线那一行,它以一个 + 开始
- 移除被添加在单词之间的多个空白空格。
第一个编辑需要匹配空行。然而。在观察输入文件时,是不容易看到这个空行有没有前导空格。事实证明它们没有,所以空行可以使用模式 “^$” 来匹配。(如果行上面有空格,模式可以写成 “^□*$”。)因此第一个编辑是相当直接就能够完成的:
s/^$/.LP/
它以 ".LP" 替换每一个空行。注意在替换命令的替换体部分,不用转义作为字面量的句号。把这个命令放在一个名为 sedscr 的文件中,然后如下测试这个命令:
➜ ch04 git:(main) ✗ sed -f sedscr horsefeathers
HORSEFEATHERS SOFTWARE PRODUCT BULLETIN
.LP
DESCRIPTION
+ ___________
.LP
BigOne Computer offers three software packages from the suite
of Horsefeathers software products -- Horsefeathers Business
BASIC, 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.
.LP
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 来简单的删除这一行。在写匹配这一行的模式时,有许多选择:
/^+/
/^+□/
/^+□□*/
/^+□□*__*
如你所见,从上往下,每个正则表达式匹配的字符越来越多。只有通过测试,才能决定要匹配一个特定的行而不是其它的行,这个正则表达式需要多复杂。在正则表达式中定义的模式越长,就越清楚地明白它不会产生不想要的匹配。对于这个脚本,选择第三个表达式:
/^+□□*/d
这个命令将删除以一个 + 开始,然后跟着至少一个空格的行。这个模式指定了两个空格,但第二个被 * 修饰,它意味着第二个空格有可能,也可能没有。
这个命令被加在 sed 脚本里,然后被测试。但是因为它只影响一行,就不展示这个结果了,继续往前。
因为这一小节太长了,所以分为两小节。
推荐文章: