被称为 tr 的小恶魔

作者:Hans de Vreught

名为 tr 的程序不是一个大型程序;它非常小巧,功能也不是特别强大。但是,如果您编写脚本,您会将其视为您的最爱之一。它是一个典型的脚本程序,从 stdin 读取并写入 stdout;无需提供文件名作为参数。主要功能是转换字符。第二个重要功能是删除字符。此外,tr 能够将重复的字符压缩为一个,但该特定功能很少使用。

让我们从转换字符开始。tr 命令的格式为

tr

当 tr 读取其输入时,它会将 string1 中出现的字符替换为 string2 中对应的字符。因此,命令 tr abc def 会将像“the quick brown fox quickly jumped over the lazy dog”这样的行替换为“the quifk erown fox quifkly jumped over the ldzy dog”。好吧,这没有意义,但它确实演示了 tr 的工作原理。

您是否曾想将文件大写或取消大写?要将其大写,您可以使用

tr abcdefghijklmnopqrstuvwxyz \
        ABCDEFGHIJKLMNOPQRSTUVWXYZ

幸运的是,我们还可以使用字符范围来更有效地指定字符

tr a-z A-Z
您是否曾经遇到过那些可怕的大写 DOS 文件名?这是一个 Bourne 脚本来处理它们
for f in *; do
      mv $f `echo $f | tr A-Z a-z`
   done
许多 UNIX 编辑器允许 shell 处理一些文本。例如,要在 vi 中将下一个段落的所有大写字符替换为小写字符,请键入
!}tr A-Z a-z
作为另一个示例,命令
!jtr a-z A-Z
将当前行和下一行大写(! 之后的字符是移动字符)。

如果您阅读国际混淆 C 代码大赛 (ftp://ftp.uu.net./pub/ioccc/),您经常会看到提示的一部分是通过一种称为 rot13 的方法编码的。rot13 是一种凯撒密码,即一种密码,其中所有字母都按一定数量的位置移动。例如,a 变为 b,b 变为 c,...,y 变为 z,z 变为 a。在 rot13 中,每个字母移动 13 个位置。它是一种弱密码,要解密它,您可以再次使用 rot13。您也可以使用 tr 以这种方式读取文本

tr a-zA-Z n-za-mN-ZA-M

tr 的另一个有趣的用法是将文件从 Macintosh 格式更改为 UNIX 格式。对于回车符,Macintosh 使用 \r,而 UNIX 使用 \n。GNU tr 允许您使用 C 特殊字符,因此键入

tr \r \n
如果您没有 GNU 版本的 tr,您可以始终使用相应的八进制数,如下所示
tr \015 \012
您可能想知道如果第二个字符串比第一个字符串短会发生什么。POSIX 说这是不允许的。System V 说只使用第一个字符串中在第二个字符串中具有匹配字符的部分。BSD 和 GNU 用其最后一个字符填充第二个字符串,以匹配第一个字符串的长度。

当我们考虑补集时,最后一种方法方便的原因变得更加清楚。假设您希望在您的列表中列出所有单词和关键字。当您使用 -c 时,tr 会补充第一个字符串。在 C 中,所有标识符和关键字都由 a-zA-Z0-9_ 组成,因此这些是我们想要保留的字符。因此,我们可以执行以下操作

tr -c a-zA-Z0-9_ \n

如果我们通过 sort -u 管道传输 tr 输出,我们将获得我们想要的列表。如果我们遵循 POSIX,则第二个字符串必须描述 193 个换行符(描述为 \n*193\n*)。如果我们使用 System V,则只有零字节被转换为换行符,因为 a-zA-Z0-9_ 的补集以零字节开头。

tr 的第二个重要用途是删除字符。对于此选项,您可以使用带有单个字符串作为参数的标志 -d。要修复那些在行尾带有 ^M 和尾随 ^Z 的讨厌的 MS-DOS 文本文件,请按以下方式指定 tr

tr -d \015\032

许多人已经用 C 编写了一个程序来执行相同的操作。好吧,C 程序不是必需的——您只需要知道正确的程序 tr,以及正确的标志。-d 标志不常用,但在需要时很好用。您可以将其与 -c 标志结合使用,以删除您作为参数提供的字符串中的字符以外的所有内容。

可以使用带有单个字符串作为参数的 -s 选项将重复的字符压缩为单个字符。它也可以用于压缩空格。要删除空行,请键入

tr -s \n

-s 选项可以与两个字符串作为参数一起使用。在这种情况下,tr 首先转换文本,就好像没有给出 -s 一样,然后尝试压缩第二个字符串中的字符。例如,我们可以通过指定以下内容将所有标准空格压缩为单个空格

tr -s   \n [ *]
-d 标志也可以与两个字符串一起使用:第一个字符串中的字符将被删除,第二个字符串中的字符将被压缩。

tr 可能不是一个伟大的程序;但是,它可以完成工作。它在使用管道和命令替换(即,在反引号内)的脚本中特别有用。如果您经常使用 tr,您将学会欣赏它的功能。小即是美。

Hans de Vreught (J.P.M.deVreught@cs.tudelft.nl) 是代尔夫特理工大学的计算机科学研究员。他自 1982 年起使用 UNIX(自 0.99.13 起使用 Linux)。他喜欢非虚拟的比利时啤酒,并且是一位真正的环球旅行家,已经环游世界两次。

加载 Disqus 评论