9.2 用 sed 转换普通文本
下面我们就为rime.txt中的文本添加一些标签,为此可以使用插入命令(i\)。找到rime.txt文件所在的路径,在shell提示符中输入下面的命令:
sed '1 i\
<!DOCTYPE html>\
<html lang="en">\
<head>\
<title>The Rime of the Ancyent Marinere (1798)</title>\
<meta charset="utf-8"/>\
</head>\
<body>\
q' rime.txt
按回车(或Return键),输出如下所示,可以看到加在上面的标签:
<!DOCTYPE html>
<html lang="en">
<head>
<title>The Rime of the Ancyent Marinere (1798)</title>
<meta charset="utf-8"/>
</head>
<body>
THE RIME OF THE ANCYENT MARINERE, IN SEVEN PARTS.
你刚刚所键入的命令并不会实际改变文件——它只会在屏幕上产生输出。后面我会展示如何修改文件内容。
9.2.1 用sed进行替换
在下面的示例中,我们要用sed找出文件的第一行然后使用转义括号\(和\)构成的捕获分组捕获一整行。sed需要对括号进行转义后才可捕获分组,除非你使用-E选项(稍后讨论)。行起始部分由^标示,行结束部分由$标示。后向引用\1将捕获的文本放入title元素中,并缩进一个空格。
运行以下命令:
sed '1s/^\(.*\)$/ <title>\1<\/title>/;q' rime.txt
输出结果如下所示:
<title>THE RIME OF THE ANCYENT MARINERE, IN SEVEN PARTS.</title>
现在试一下这样:
sed -E '1s/^(.*)$/<!DOCTYPE html>\
<html lang="en">\
<head>\
<title>\1<\/title>\
<\/head>\
<body>\
<h1>\1<\/h1>\
/;q' rime.txt
以下是详细分析。
· -E选项代表sed使用扩展的正则表达式(也就是ERE,因此不必对括号进行转义)。
· 使用替换命令时,将第1行放入捕获分组(^(.*)$)因此可以通过\1重用该内容。
· 创建HTML标签以及用\对换行符进行转义。
· 在title和h1之间用\1插入捕获的文本。
· 在q处结束程序来防止在屏幕上打印剩下的诗文。
正确的结果是:
<!DOCTYPE html>
<html lang="en">
<head>
<title>THE RIME OF THE ANCYENT MARINERE, IN SEVEN PARTS.</title>
</head>
<body>
<h1>THE RIME OF THE ANCYENT MARINERE, IN SEVEN PARTS.</h1>
9.2.2 用sed处理罗马数字
诗文分为七个部分,每一部分以一个罗马数字开头。还有一个“ARGUMENT”标题。下面一行命令会使用sed捕获标题和罗马数字,并将它们用<h2>标签包括:
sed -En 's/^(ARGUMENT\.|I{0,3}V?I{0,2}\.)$/<h2>\1<\/h2>/p' rime.txt
以下就是你会看到的结果:
<h2>ARGUMENT\.</h2>
<h2>I.</h2
<h2>II.</h2
<h2>III.</h2
<h2>IV.</h2
<h2>V.</h2
<h2>VI.</h2
<h2>VII.</h2
接下来是对以上sed命令的描述。
· -E选项会使用扩展的正则表达式,而-n选项会覆盖sed默认打印每一行的行为。
· 替换命令(s)会捕获标题和七个大写罗马数字,其中每一个单独一行紧跟一个句号,范围为I到VII。
· s命令随后将每一行捕获的文本嵌入h2元素中。
· 替换部分末尾的p标志将结果打印到屏幕上。
9.2.3 用sed处理特定段落
接下来这行命令会找到第5行的段落:
sed -En '5s/^([A-Z].*)$/<p>\1<\/p>/p' rime.txt
然后将该段落放入<p>标签中:
<p>How a Ship having passed the Line was driven by Storms to the cold Country towards
the South Pole; and how from thence she made her course to the tropical Latitude
of the Great Pacific Ocean; and of the strange things that befell; and in what
manner the Ancyent Marinere came back to his own Country.</p>
进展有点儿慢?别急,我们很快就会把这些技巧综合起来。
9.2.4 用sed处理多行诗文
接着我们使用下面的表达式来标记多行诗文:
sed -E '9s/^[ ]*(.*)/ <p>\1<br\/>/;10,832s/^([ ]{5,7}.*)/\1<br\/>/;833s/^(.*)/\1<\/p>/' rime.txt
这些sed命令是根据行号来实现操作的。通常情况下这种方法并不适用,但若所处理的内容已知则这种方法还是很好的。
· 第9行(诗文的第一行,s命令会选定该行),在文字前面添加几个空格,再插入一个<p>标签,然后在行尾添加一个<br>标签。
· 第10行到第832行,每个开头有5至7个空格的行之后都添加一个<br>标签。
· 在第833行(诗文的最后一行),s命令添加</p>标签而不是<br>标签。
这里是标记后的部分结果:
<p>It is an ancyent Marinere,<br/>
And he stoppeth one of three:<br/>
"By thy long grey beard and thy glittering eye<br/>
"Now wherefore stoppest me?<br/>
"The Bridegroom's doors are open'd wide<br/>
"And I am next of kin;<br/>
"The Guests are met, the Feast is set,--<br/>
"May'st hear the merry din.--<br/>
还应该用<br>标签替代空行来分隔诗文:
sed -E 's/^$/<br\/>/' rime.txt
下面是操作的结果:
He prayeth best who loveth best,
All things both great and small:
For the dear God, who loveth us,
He made and loveth all.
<br/>
The Marinere, whose eye is bright,
Whose beard with age is hoar,
Is gone; and now the wedding-guest
Turn'd from the bridegroom's door.
<br/>
He went, like one that hath been stunn'd
And is of sense forlorn:
A sadder and a wiser man
He rose the morrow morn.
我发现在合适的位置添加标签和空格实在太常见了。希望你也能做好。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论