sed命令示例:'r'

‘r’命令用来读入文本。与’a’的作用相似,但文本是放在独立的文件而不是放在脚本中。用’r’的好处在于将数据与脚本独立,使脚本更易读并且修改数据文件更方便。

用法

这是GNU sed自带文档中对’r’命令的说明:

r filename
Queue the contents of filename to be read and inserted into the output stream at the end of the current cycle, or when the next input line is read. Note that if filename cannot be read, it is treated as if it were an empty file, without any error indication.

GNU对这个命令进行了扩展:

  • 接受两个地址。可以对一定的地址区间进行操作
  • 允许使用/dev/stdin作为文件名
  • 新增了一个R命令。这个命令用法与r一样但一次只读入一行。

另外一些需要注意的地方:

  • 文件不能读取时,则当成空文件处理不会有出错信息。
  • r 命令之后不能再使用其他命令,因而如果后面的命令要另起一行或以’-e’选项隔开。
  • r是在当前的cycle结束后才在最后加入内容的,所以在无法在cycle中对读入的内容进行操作的。

实例

我一向认为一个例子比得上千言万语。看个例子先:现有一个网页要进行如下修改,在中增加标签。在标签前增加版权声明的标签。我们将要在标签后的内容放在meta.tag中。将放在文件未尾的内容放在copyleft.tag中。里面的内容如下:

1
2
3
4
$ cat meta.tag

$ cat copyleft.tag
版权所有……

我们需要的命令是:

1
2
3
4
5
sed '/< /title>/r meta.tag
/< /body>/{
x
r copyleft.tag
G}' samp.html

写成单行的形式就是:

1
sed -e '/< /title>/r meta.tag' -e '/< /body>/{x;r copyleft.tag' -e 'G}' samp.html

如果你在Windows的命令行上使用的话,那就根据你所用的版本将单引号相应的改为双引号。不过请务必注意上面脚本是一个简化的情形,因为标签也可能有大写字母(更复杂的情形是title后的方括号也许在下面一行)(虽然W3C的XHTML中要求标签必须是小写,但这种可能性是存在的视你自已的情况而定。)如果你用的是GNU sed的话那恭喜,你可以在式样后使用’I’修改符(modifier):/< /title>/I。否则:/< /[tT][iI] [tT][lL][eE]>/当然偶尔可以偷懒:/< /[tT].[tT].[eE]>/。

实例:批量修改

当然我们想修改的通常不会只是一个文件,于是我们需要用到shell(注意文件的读写权限):

1
2
3
4
5
$ for a in 'find . -name "*.html"'
do
mv $a $a.bak
sed -e '/< /title>/r meta.tag' -e '/< /body>/{x;r copyleft.tag' -e 'G}' $a.bak >$a
done

find有一个-exec,但是如果参数太多会出错因而这里使用了for命令。
如果是Windows平台:

1
2
3
4
for /R %a in (*.html) do @copy %a %a.bak & @sed -e "…" %a.bak>%a
``
在批处理中使用时记得要用'%%'代替'%'。
如果你用的是GNU sed 4.0或以上版本,那你可以使用-i选项代替'mv'命令:

$ for a in ‘find . -name “*.html”‘
do
gsed -i.bak -e ‘
/< /title>/r meta.tag
/< /body>/{
x
r copyleft.tag
G}’ $a
done
`