Archive for 2008 年 5 月 18 日

sed命令示例:`r’

0

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中。里面的内容如下:


$ cat meta.tag

$ cat copyleft.tag

版权所有……

我们需要的命令是:

sed ‘/< /title>/r meta.tag
/< /body>/{
x
r copyleft.tag
G}’ samp.html

写成单行的形式就是:

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

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

实例:批量修改

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


$ 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平台:

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

Footnotes

[1] 更复杂的情形是title后的方括号也许在下面一行。

SED单行脚本快速参考

0

最近版本的SED ONE-LINER现在可以在sed.sourceforge.net上找到了。有多个语言版本也包括了简体中文版本。意大利语和西班牙语的翻译也正在进行中。

SED单行脚本快速参考(Unix 流编辑器) 2005年12月29日

英文标题:USEFUL ONE-LINE SCRIPTS FOR SED (Unix stream editor)
原标题:HANDY ONE-LINERS FOR SED (Unix stream editor)

整理:Eric Pement – 电邮:pemente[at]northpark[dot]edu 版本5.5
译者:Joe Hong – 电邮:hq00e[at]126[dot]com

在以下地址可找到本文档的最新(英文)版本:
http://sed.sourceforge.net/sed1line.txt
http://www.pement.org/sed/sed1line.txt

其他语言版本:
中文 – http://sed.sourceforge.net/sed1line_zh-CN.html
捷克语 – http://sed.sourceforge.net/sed1line_cz.html
荷语 – http://sed.sourceforge.net/sed1line_nl.html
法语 – http://sed.sourceforge.net/sed1line_fr.html
德语 – http://sed.sourceforge.net/sed1line_de.html
葡语 – http://sed.sourceforge.net/sed1line_pt-BR.html

EDITPLUS 揭开正则表达式的神秘面纱

0

引言
正则表达式(regular expression)就是用一个“字符串”来描述一个特征,然后去验证另一个“字符串”是否符合这个特征。比如 表达式“ab+” 描述的特征是“一个 ‘a’ 和 任意个 ‘b’ ”,那么 ‘ab’, ‘abb’, ‘abbbbbbbbbb’ 都符合这个特征。

正则表达式可以用来:(1)验证字符串是否符合指定特征,比如验证是否是合法的邮件地址。(2)用来查找字符串,从一个长的文本中查找符合指定特征的字符串,比查找固定字符串更加灵活方便。(3)用来替换,比普通的替换更强大。

正则表达式学习起来其实是很简单的,不多的几个较为抽象的概念也很容易理解。之所以很多人感觉正则表达式比较复杂,一方面是因为大多数的文档没有做到由浅入深地讲解,概念上没有注意先后顺序,给读者的理解带来困难;另一方面,各种引擎自带的文档一般都要介绍它特有的功能,然而这部分特有的功能并不是我们首先要理解的。

文章中的每一个举例,都可以点击进入到测试页面进行测试。闲话少说,开始。

——————————————————————————–

1. 正则表达式规则
1.1 普通字符
字母、数字、汉字、下划线、以及后边章节中没有特殊定义的标点符号,都是”普通字符”。表达式中的普通字符,在匹配一个字符串的时候,匹配与之相同的一个字符。

举例1:表达式 “c”,在匹配字符串 “abcde” 时,匹配结果是:成功;匹配到的内容是:”c”;匹配到的位置是:开始于2,结束于3。(注:下标从0开始还是从1开始,因当前编程语言的不同而可能不同)

举例2:表达式 “bcd”,在匹配字符串 “abcde” 时,匹配结果是:成功;匹配到的内容是:”bcd”;匹配到的位置是:开始于1,结束于4。

——————————————————————————–

1.2 简单的转义字符
一些不便书写的字符,采用在前面加 “” 的方法。这些字符其实我们都已经熟知了。

表达式
可匹配

r, n
代表回车和换行符

t
制表符

\
代表 “” 本身

还有其他一些在后边章节中有特殊用处的标点符号,在前面加 “” 后,就代表该符号本身。比如:^, $ 都有特殊意义,如果要想匹配字符串中 “^” 和 “$” 字符,则表达式就需要写成 “^” 和 “$”。

表达式
可匹配

^
匹配 ^ 符号本身

$
匹配 $ 符号本身

.
匹配小数点(.)本身

这些转义字符的匹配方法与 “普通字符” 是类似的。也是匹配与之相同的一个字符。

举例1:表达式 “$d”,在匹配字符串 “abc$de” 时,匹配结果是:成功;匹配到的内容是:”$d”;匹配到的位置是:开始于3,结束于5。

——————————————————————————–

1.3 能够与 ‘多种字符’ 匹配的表达式
正则表达式中的一些表示方法,可以匹配 ‘多种字符’ 其中的任意一个字符。比如,表达式 “d” 可以匹配任意一个数字。虽然可以匹配其中任意字符,但是只能是一个,不是多个。这就好比玩扑克牌时候,大小王可以代替任意一张牌,但是只能代替一张牌。

表达式
可匹配

d
任意一个数字,0~9 中的任意一个

w
任意一个字母或数字或下划线,也就是 A~Z,a~z,0~9,_ 中任意一个

s
包括空格、制表符、换页符等空白字符的其中任意一个

.
小数点可以匹配除了换行符(n)以外的任意一个字符

举例1:表达式 “dd”,在匹配 “abc123″ 时,匹配的结果是:成功;匹配到的内容是:”12″;匹配到的位置是:开始于3,结束于5。

举例2:表达式 “a.d”,在匹配 “aaa100″ 时,匹配的结果是:成功;匹配到的内容是:”aa1″;匹配到的位置是:开始于1,结束于4。

——————————————————————————–

1.4 自定义能够匹配 ‘多种字符’ 的表达式
使用方括号 [ ] 包含一系列字符,能够匹配其中任意一个字符。用 [^ ] 包含一系列字符,则能够匹配其中字符之外的任意一个字符。同样的道理,虽然可以匹配其中任意一个,但是只能是一个,不是多个。

表达式
可匹配

[ab5@]
匹配 “a” 或 “b” 或 “5″ 或 “@”

[^abc]
匹配 “a”,”b”,”c” 之外的任意一个字符

[f-k]
匹配 “f”~”k” 之间的任意一个字母

[^A-F0-3]
匹配 “A”~”F”,”0″~”3″ 之外的任意一个字符

举例1:表达式 “[bcd][bcd]” 匹配 “abc123″ 时,匹配的结果是:成功;匹配到的内容是:”bc”;匹配到的位置是:开始于1,结束于3。

举例2:表达式 “[^abc]” 匹配 “abc123″ 时,匹配的结果是:成功;匹配到的内容是:”1″;匹配到的位置是:开始于3,结束于4。

——————————————————————————–

1.5 修饰匹配次数的特殊符号
前面章节中讲到的表达式,无论是只能匹配一种字符的表达式,还是可以匹配多种字符其中任意一个的表达式,都只能匹配一次。如果使用表达式再加上修饰匹配次数的特殊符号,那么不用重复书写表达式就可以重复匹配。

使用方法是:”次数修饰”放在”被修饰的表达式”后边。比如:”[bcd][bcd]” 可以写成 “[bcd]{2}”。

表达式
作用

{n}
表达式重复n次,比如:”w{2}” 相当于 “ww”;”a{5}” 相当于 “aaaaa”

{m,n}
表达式至少重复m次,最多重复n次,比如:”ba{1,3}”可以匹配 “ba”或”baa”或”baaa”

{m,}
表达式至少重复m次,比如:”wd{2,}”可以匹配 “a12″,”_456″,”M12344″…

?
匹配表达式0次或者1次,相当于 {0,1},比如:”a[cd]?”可以匹配 “a”,”ac”,”ad”

+
表达式至少出现1次,相当于 {1,},比如:”a+b”可以匹配 “ab”,”aab”,”aaab”…

*
表达式不出现或出现任意次,相当于 {0,},比如:”^*b”可以匹配 “b”,”^^^b”…

举例1:表达式 “d+.?d*” 在匹配 “It costs $12.5″ 时,匹配的结果是:成功;匹配到的内容是:”12.5″;匹配到的位置是:开始于10,结束于14。

举例2:表达式 “go{2,8}gle” 在匹配 “Ads by goooooogle” 时,匹配的结果是:成功;匹配到的内容是:”goooooogle”;匹配到的位置是:开始于7,结束于17。

——————————————————————————–

1.6 其他一些代表抽象意义的特殊符号
一些符号在表达式中代表抽象的特殊意义:

表达式
作用

^
与字符串开始的地方匹配,不匹配任何字符

$
与字符串结束的地方匹配,不匹配任何字符

b
匹配一个单词边界,也就是单词和空格之间的位置,不匹配任何字符

进一步的文字说明仍然比较抽象,因此,举例帮助大家理解。

举例1:表达式 “^aaa” 在匹配 “xxx aaa xxx” 时,匹配结果是:失败。因为 “^” 要求与字符串开始的地方匹配,因此,只有当 “aaa” 位于字符串的开头的时候,”^aaa” 才能匹配,比如:”aaa xxx xxx”。

举例2:表达式 “aaa$” 在匹配 “xxx aaa xxx” 时,匹配结果是:失败。因为 “$” 要求与字符串结束的地方匹配,因此,只有当 “aaa” 位于字符串的结尾的时候,”aaa$” 才能匹配,比如:”xxx xxx aaa”。

举例3:表达式 “.b.” 在匹配 “@@@abc” 时,匹配

Go to Top