通用线程--sed 实例,第2部分( 二 )


"[ ]" 规则表达式语法还有一些附加选项 。要指定字符范围,只要字符不在第一个或最后一个位置,就可以使用 "-",如下所示:"[a-x]*"
这将匹配零或多个全部为 "a"、"b"、"c"..."v"、"w"、"x" 的字符 。另外,可以使用 "[:space:]" 字符类来匹配空格 。以下是可用字符类的相当完整的列表:字符类 描述
[:alnum:] 字母数字 [a-z A-Z 0-9]
[:alpha:] 字母 [a-z A-Z]
[:blank:] 空格或制表键
[:cntrl:] 任何控制字符
[:digit:] 数字 [0-9]
[:graph:] 任何可视字符(无空格)
[:lower:] 小写 [a-z]
[:print:] 非控制字符
[:punct:] 标点字符
[:space:] 空格
[:upper:] 大写 [A-Z]
[:xdigit:] 十六进制数字 [0-9 a-f A-F]尽可能使用字符类是很有利的,因为它们可以更好地适应非英语 locale(包括某些必需的重音字符等等).高级替换功能
我们已经看到如何执行简单甚至有些复杂的直接替换,但是 sed 还可以做更多的事 。实际上可以引用匹配规则表达式的部分或全部,并使用这些部分来构造替换字符串 。作为示例,假设您正在回复一条消息 。下例将在每一行前面加上短语 "ralph said: ":$ sed -e "s/.*/ralph said: &/" origmsg.txt
输出如下:ralph said: Hiya Jim, ralph said: ralph said:
I sure like this sed stuff! ralph said:
该例的替换字符串中使用了 "&" 字符,该字符告诉 sed 插入整个匹配的规则表达式 。因此,可以将与 ".*" 匹配的任何内容(行中的零或多个字符的最大组或整行)插入到替换字符串中的任何位置,甚至多次插入 。这非常好,但 sed 甚至更强大 。那些极好的带反斜杠的圆括号
"s///" 命令甚至比 "&" 更好,它允许我们在规则表达式中定义区域,然后可以在替换字符串中引用这些特定区域 。作为示例,假设有一个包含以下文本的文件:foo bar oni eeny meeny miny larry curly moe jimmy the weasel
现在假设要编写一个 sed 脚本,该脚本将把 "eeny meeny miny" 替换成 "Victor eeny-meeny Von miny" 等等 。要这样做,首先要编写一个由空格分隔并与三个字符串匹配的规则表达式 。".* .* .*"
现在,将在其中每个感兴趣的区域两边插入带反斜杠的圆括号来定义区域:"(.*) (.*) (.*)"
除了要定义三个可在替换字符串中引用的逻辑区域以外,该规则表达式的工作原理将与第一个规则表达式相同 。下面是最终脚本:$ sed -e "s/(.*) (.*) (.*)/Victor 1-2 Von 3/" myfile.txt
如您所见,通过输入 "x"(其中,x 是从 1 开始的区域号)来引用每个由圆括号定界的区域 。输入如下:Victor foo-bar Von oni Victor eeny-meeny Von miny Victor larry-curly Von moe Victor jimmy-the Von weasel
随着对 sed 越来越熟悉,您可以花最小力气来进行相当强大的文本处理 。您可能想如何使用熟悉的脚本语言来处理这种问题 -- 能用一行代码轻易实现这样的解决方案吗?组合使用
在开始创建更复杂的 sed 脚本时,需要有输入多个命令的能力 。有几种方法这样做 。首先,可以在命令之间使用分号 。例如,以下命令系列使用 "=" 命令和 "p" 命令,"=" 命令告诉 sed 打印行号,"p" 命令明确告诉 sed 打印该行(因为处于 "-n" 模式) 。$ sed -n -e "=;p" myfile.txt
无论什么时候指定了两个或更多命令,都按顺序将每个命令应用到文件的每一行 。在上例中,首先将 "=" 命令应用到第 1 行,然后应用 "p" 命令 。接着,sed 继续处理第 2 行,并重复该过程 。虽然分号很方便,但是在某些场合下,它不能正常工作 。另一种替换方法是使用两个 -e 选项来指定两个不同的命令:$ sed -n -e "=" -e "p" myfile.txt
然而,在使用更为复杂的附加和插入命令时,甚至多个 "-e" 选项也不能帮我们的忙 。对于复杂的多行脚本,最好的方法是将命令放入一个单独的文件中 。然后,用 -f 选项引用该脚本文件:$ sed -n -f mycommands.sed myfile.txt

推荐阅读