如何使用 Linux tr 命令
在 Linux 上转换文本流的最简单方法。
要点
tr 命令对文本流执行转换,生成一个新的流作为其输出。您可以根据在命令行上设置的规则替换、删除或转换字符。
您是否需要一种简单的方法来在 Linux 中操作文本流? tr 命令就是您的最佳选择,它可以节省您替换、删除、组合和压缩输入文本的时间。就是这样完成的。
tr 命令是什么?
Linux tr
命令是一个快速而简单的实用程序,用于从文本流中删除不需要的字符,以及其他巧妙的操作技巧。它的名字来源于“翻译”一词,tr
的根源深深植根于 Unix 传统。
众所周知,Linux 是 Unix 的开源重写。它还添加了自己的东西。它不是逐个字节的克隆,但它显然从 Unix 操作系统中汲取了大部分设计原则和工程指导。
尽管迄今为止只有两个 Linux 发行版获得了 POSIX 兼容认证并被正式接受为 Unix 的实现——EulerOS 和 Inspur K-UX——但 Linux 在商业领域几乎完全取代了 Unix。
所有 Linux 发行版,至少在其核心实用程序中,都遵循 Unix 哲学。 Unix 哲学概括了 Unix 先驱者对其新操作系统的愿景。它通常被解释为“编写能做好一件事的程序”。但还有更多的事情要做。
最强大的创新之一是项目应该产生可用作其他项目输入的输出。将命令行实用程序菊花链在一起的能力非常强大,使用一个程序的输出流作为下一个程序的输入流。
有时,您需要在一个程序到达下一个程序之前对其输出进行微调或调整。或者,您可能没有从 Linux 命令行工具获取输入,而是从尚未根据您的特定需求创建的文件中流式传输文本。
这就是 tr
发挥作用的地方。它允许您对其输入流执行一组简单的转换,以生成其输出流。该输出流可以重定向到一个文件中,输入到另一个 Linux 程序中,甚至输入到另一个 tr
实例中,以便对流应用多个转换。
替换字符
tr
命令根据规则对其输入流进行操作。在不使用任何命令行选项的情况下,tr
的默认操作是将输入流中的字符替换为其他字符。
tr
命令通常需要两组字符。第一组包含如果在输入流中找到则将被替换的字符。第二组包含将被替换的字符。
其工作原理是,第一组中出现的第一个字符将被第二组中的第一个字符替换。第一组中第二个字符的出现将被第二组中的第二个字符替换,依此类推。
此示例将在 tr
的输入流中查找字母“c”,并将每个出现的字母替换为字母“z”。请注意,tr
区分大小写。
我们正在使用
echo
将一些文本推入 tr
。
echo abcdefabc | tr 'c' 'z'
所有出现的“c”都将替换为“z”,并将新字符串写入终端窗口。
这次我们将搜索两个字母“a”和“c”。请注意,我们不是在搜索“ac”。我们正在寻找“a”,然后寻找“c”。我们将用“x”替换所有出现的“a”,用“z”替换所有出现的“c”。
echo abcdefabc | tr 'ac' 'xz'
为此,两个集合中的字符数必须相同。如果不这样做,您将得到可预测但可能不想要的行为。
echo 'call me Ishmael.' | tr 'abcdjklm' '123'
第一组中的角色比第二组中的角色多。字母“d”到“m”在第二组中没有对应的字符。它们仍然会被替换,但它们都会被第二组中的最后一个字符替换。
这在某些情况下可能很有用,但如果您想防止这种情况,可以使用 -t
(截断)选项。这仅替换第一组中包含的那些在第二组中具有匹配字符的字符。
echo 'call me Ishmael.' | tr -t 'abcdjklm' '123'
使用范围和标记
集合一和集合二可以包含字符范围。例如,[a-z]
表示所有小写字母,[A-Z]
表示所有大写字母。我们可以利用它来更改文本流的大小写。
这会将输入流转换为大写。
echo "How-To Geek" | tr '[a-z]' '[A-Z]'
要向另一个方向翻转大小写,我们可以使用相同的命令,但在命令行上交换大小写范围。
echo "How-To Geek" | tr '[A-Z]' '[a-z]'
我们可以将一些标记用于我们可能想要匹配的一些常见情况。
- [:alnum:]:字母和数字。
- [:alpha:]:仅限字母。
- [:digit:]:仅限数字。
- [:blank:]:制表符和空格。
- [:space:]:所有空格,包括换行符。
- [:graph:]:所有字符,包括符号,但不包括空格。
- [:print:]:所有字符,包括符号,包括空格。
- [:punct:]:所有标点符号。
- [:lower:]:小写字母。
- [:upper:]:大写字母。
我们可以使用标记同样轻松地执行小写到大写和大写到小写的转换。
echo "How-To Geek" | tr '[:lower:]' '[:upper:]'
echo "How-To Geek" | tr '[:upper:]' '[:lower:]'
反转匹配
-c
(补码)选项匹配除第一组字符之外的所有字符。此命令将除字母“c”之外的所有内容转换为连字符“-
”。
echo abcdefc | tr -c 'c' '-'
此命令将字母“a”添加到第一组中。除“a”或“c”之外的任何内容都将转换为连字符“ -
”。
echo abcdefc | tr -c 'ac' '-'
删除和压缩字符
我们可以使用 tr
完全删除字符,而不进行任何替换。
此命令使用 -d
(删除)选项从输入流中删除任何出现的“a”、“d”或“f”。
echo abcdefc | tr -d 'adf'
在这个例子中,我们的命令行上只有一组字符,而不是两组。
另一种情况是我们使用 -s (squeeze-repeats) 选项。此选项将重复字符减少为单个字符。
此示例将把重复的空格字符序列减少为单个空格。
echo "a b c de f c" | tr -s '[:blank:]'
有点令人困惑的是,[:blank:]
标记表示空格字符,而 [:space:]
标记表示所有形式的空白,包括制表符和换行符。
在这种情况下,我们可以将 [:blank:]
替换为 [:space:]
并获得相同的结果。
echo "a b c de f c" | tr -s '[:space:]'
删除字符
当我们删除字符时,[:blank:]
和 [:space:]
之间的差异变得明显。为此,我们使用 -d
(删除)选项,并提供 tr
将在其输入流中查找的一组字符。它发现的任何内容都会被删除。
echo "a b c de f c" | tr -d '[:blank:]'
空格被删除。请注意,在终端窗口中写入输出流后,我们会得到一个换行符。如果我们重复该命令并使用 [:space:]
而不是空白,我们将得到不同的结果。
echo "a b c de f c" | tr -d '[:blank:]'
这次我们不在输出后开始新行,命令提示符直接与它对接。这是因为 [:space:]
包含换行符。所有空格、制表符和换行符都将从输入流中删除。
当然,您也可以使用实际的空格字符。
echo "a b c de f c" | tr -d ' '
我们可以同样轻松地删除数字。
echo abcd123efg | tr -d '[:digit:]'
通过组合 -c
(补码)和 -d
(删除)选项,我们可以删除除数字之外的所有内容。
echo abcd123efg | tr -cd '[:digit:]'
请注意,除了数字之外的所有内容都意味着所有字母和所有空格,因此我们再次丢失了终止换行符。
合并和分割线
如果我们用换行符替换空格,我们可以分割一行文本并将每个单词放在自己的行上。
echo 'one two three four' | tr ' ' '\n'
我们也可以更改分隔单词的分隔符。此命令用冒号“ :
”代替空格。
echo 'one two three four' | tr ' ' ':'
我们可以找到正在使用的任何分隔符,并将其替换为换行符,将难以阅读的文本拆分为更易于管理的输出。
path环境变量是一长串许多目录路径。冒号“ :
”分隔每个路径。我们将它们更改为换行符。
echo $PATH
echo $PATH | tr ":" "\n"
这更容易直观地解析。
如果我们想要将输出重新格式化为一行,我们也可以这样做。文件“lines.txt”包含一些文本,每行一个单词。我们将其输入 tr
并将其转换为单行。
cat files.txt
cat lines.txt | tr '\n' ' '
将 tr 与管道一起使用
我们可以使用 tr 的输出作为另一个程序的输入,甚至是 tr 本身的输入。
此命令使用 tr
四次。
- 第一个
tr
从输入中删除所有连字符“-”。 - 第二个
tr
将所有重复的空格压缩为单个空格。 - 第三个
tr
用下划线“_”字符替换空格。 - 第四个也是最后一个
tr
将字符串转换为小写。
echo "Mangled FiLE-nAMe.txt" | tr -d '-' | tr -s ' ' | tr ' ' '_' | tr '[:upper:]' '[:lower:]'
相关:如何在 Linux 上使用管道
简单就是简单
tr
命令很棒,因为它很简单。没有太多需要学习或记住的东西。但它的简单性也可能是它的缺点。
毫无疑问,您经常会发现 tr
让您可以做您需要的事情,而无需使用 sed
等更复杂的工具。
相关:如何在 Linux 上使用 sed 命令
但是,如果您正在努力使用 tr
执行某些操作,并且发现自己正在构建长菊花链命令,那么您可能应该使用 sed
。