如何使用 Linux cat 和 tac 命令

cattac 命令看似简单,它们主要用于显示文本文件的内容,但实际上它们的功能远比表面看起来的要强大。 让我们深入了解一下,学习一些高效的 Linux 命令行技巧。

这两个命令通常被认为是基础且简单的工具,似乎没有太多实际用途。然而,一旦你掌握了它们的不同用法,你会发现它们在处理文件时能承担很多繁重的工作。

cat 命令详解

cat 命令的主要作用是查看文本文件的内容,并将多个文件合并成一个更大的文件。

在拨号上网时代,调制解调器传输速度有限,大型二进制文件通常会被分割成多个小文件,以便于下载。用户不会下载一个完整的大文件,而是下载一系列小文件。如果某个小文件下载失败,用户只需要重新下载该文件即可。

当然,用户需要一种方法将这些小文件重新组合成一个可用的二进制文件,这个过程称为连接。这正是 cat 命令的用途,也是它名字的由来。

随着宽带和光纤连接的普及,这种需求已经逐渐减少。那么,现在的 cat 命令还能做什么呢? 实际上,它仍然有许多用途。

显示文本文件内容

要使用 cat 命令将文本文件的内容显示在终端窗口中,可以使用以下命令:

请确保你要操作的文件是文本文件。 如果你试图显示二进制文件的内容,可能会导致无法预料的结果,甚至可能导致终端会话锁定或更严重的问题。

cat poem1.txt

终端窗口将显示 `poem1.txt` 文件的内容。

这只是一首著名诗歌的一部分,那另一部分在哪里呢?这里还有一个名为 `poem2.txt` 的文件。我们可以使用 cat 命令一次性显示多个文件的内容,只需在命令行中按顺序列出这些文件即可。

cat poem1.txt poem2.txt

现在内容看起来完整了,我们看到了整首诗。

使用 less 命令浏览输出

虽然现在这首诗显示出来了,但内容滚动太快,无法阅读开头的部分。我们可以将 cat 命令的输出通过管道传递给 less 命令,以便我们可以按照自己的节奏滚动浏览文本。

cat poem1.txt poem2.txt | less

现在,即使文本存储在两个单独的文件中,我们也可以轻松地在整个文本中前后移动。

对文件中的行进行编号

我们还可以在显示文件内容时对行进行编号。 使用 `-n` (number) 选项即可实现此功能。

cat -n poem1.txt

终端窗口中显示的行现在都带有编号。

忽略空行进行编号

我们成功地使用 cat 命令对行进行了编号,但是诗句之间的空行也被计算在内了。 如果要对文本行进行编号,但忽略空行,可以使用 `-b` (number-nonblank) 选项。

cat -b poem1.txt

现在,只有文本行被编号,空行被跳过。

压缩多个空行

如果文件中存在连续的空行,我们可以让 cat 命令忽略除一个空行之外的所有空行。 看一下这个文件:

以下命令将使 cat 命令在每个空行组中只显示一个空行。 我们需要使用 `-s` (squeeze-blank) 选项来实现此操作。

cat -s poem1.txt

这不会以任何方式修改文件的内容,它只是改变了 cat 命令显示文件的方式。

显示制表符

如果你想知道空格是由空格还是制表符产生的,可以使用 `-T` (show-tabs) 选项来查找。

cat -T poem1.txt

制表符由字符 “^I” 表示。

显示行尾

你可以使用 `-E` (show-ends) 选项来检查行尾是否有多余的空格。

cat -E poem1.txt

行尾由 “$” 字符表示。

合并文件

将一首诗分成两个文件,每个文件各占一半,是毫无意义的。 让我们将它们合并成一个新文件,其中包含整首诗。

cat poem1.txt poem2.txt > jabberwocky.txt

让我们使用 cat 命令检查一下新文件:

cat jabberwocky.txt

现在,我们的新文件包含了另外两个文件的内容。

将文本追加到现有文件

这样看起来好多了,但实际上,这并不是完整的诗。 最后一节丢失了。 《Jabberwocky》的最后一节与第一节相同。

如果我们在文件中保存了第一节诗,我们可以将其附加到 `jabberwocky.txt` 文件的末尾,这样我们就得到了完整的诗。

在接下来的命令中,我们必须使用 `>>`,而不是 `>`。 如果我们使用单个 `>`,那么我们将会覆盖 `jabberwocky.txt` 文件,这不是我们想要的结果,我们只想把文本追加到文件的末尾。

cat first_verse.txt >> jabberwocky.txt

让我们检查一下 `jabberwocky.txt` 文件的内容:

cat jabberwocky.txt

终于,这首诗的所有部分都整合在一起了。

重定向标准输入

你可以使用 cat 命令将键盘的输入重定向到一个文件中。 你输入的所有内容都会被重定向到文件中,直到你按下 Ctrl+D。请注意,我们这里使用单个 `>`,因为我们要创建文件(或者覆盖它,如果它已存在)。

cat > my_poem.txt

我们输入完命令后就可以开始输入内容。 完成后,我们按下 Ctrl+D。 然后我们可以检查新文件的内容:

cat my-poem.txt

听起来像是遥远的涡轮机的声音可能是刘易斯卡罗尔在坟墓里高速旋转。

tac 命令

tac 命令类似于 cat 命令,但它以相反的顺序显示文件的内容。

让我们来看一下:

tac my_poem.txt

该文件以相反的顺序显示在终端窗口中。 在这种情况下,它对文本的文学价值没有影响。

使用 tac 命令和标准输入

如果 tac 命令不带文件名参数,它会处理来自键盘的输入。 按下 Ctrl+D 将停止输入,tac 命令会以相反的顺序显示你输入的任何内容。

tac

按下 Ctrl+D 后,输入的内容将被反转并显示在终端窗口中。

tac 命令用于日志文件

除了以上这些小技巧,tac 命令还能做什么有用的事情呢? 是的,它可以。 许多日志文件会将最新的条目添加到文件末尾。 使用 tac 命令(以及有些违反直觉的 `head` 命令),我们可以将最新的条目输出到终端窗口中。

我们使用 tac 命令以相反的顺序显示 `syslog` 文件,并将输出通过管道传递给 `head` 命令。 通过告诉 `head` 命令只打印它接收到的第一行(由于 tac 命令,这实际上是文件中的最后一行),我们可以查看 `syslog` 文件中的最新条目。

tac /var/log/syslog | head -1

`head` 命令输出了 `syslog` 文件中的最新条目,然后退出。

请注意,`head` 命令只输出了一行,就像我们要求的那样,但由于这行的内容太长,它绕了两圈显示。 这就是为什么它在终端窗口中看起来像是三行输出的原因。

tac 命令用于文本记录

tac 命令的最后一个技巧非常实用。

通常,tac 命令从下往上逐行处理文本文件。 行是由换行符分隔的字符序列。 但是,我们可以告诉 tac 命令使用其他分隔符。 这允许我们将文本文件中的数据 “块” 视为数据记录。

假设我们有一个来自某个程序的日志文件,我们需要查看或分析。 让我们使用 less 命令来查看它的格式。

less logfile.dat

正如我们看到的,文件有一个重复的格式。 有三个十六进制数值组成的序列。每组三行十六进制数据前面都有一个标签行,以 “=SEQ” 开头,后跟一个数字序列。

如果我们滚动到文件的底部,我们可以看到有很多这样的记录。 最后一个记录的编号为 865。

假设由于某种原因,我们需要以相反的顺序处理这个文件,一个数据记录一个数据记录。 必须保留每个数据记录中三行十六进制数据的行序。

请注意,文件中最后三行的十六进制值分别以 93、E7 和 B8 开头,并且顺序排列。

让我们使用 tac 命令来反转文件,由于这是一个很长的文件,所以我们将它导入到 less 命令中。

tac logfile.dat | less

这会反转整个文件,但这不是我们想要的结果。 我们希望文件被反转,但每个数据记录中的行必须保持原始顺序。

我们之前记录了文件中最后三行的十六进制值分别以 93、E7 和 B8 开头,并且顺序排列,现在这些行的顺序已经被颠倒了。 此外, “=SEQ” 行现在位于每组三行十六进制数据的下方。

tac 命令可以帮我们解决这个问题。

tac -b -r -s ^=SEQ.+[0-9]+*$ logfile.dat | less

让我们分解一下这个命令:

`-s` (分隔符) 选项告诉 tac 命令使用什么作为记录之间的分隔符。它告诉 tac 命令不要使用默认的换行符,而是使用我们指定的分隔符。

`-r` (正则表达式) 选项告诉 tac 命令将分隔符字符串视为正则表达式

`-b` (before) 选项使 `tac` 命令在每条记录之前而不是之后显示分隔符(这是其默认分隔符的通常位置,即换行符)。

`-s` (分隔符) 字符串 `^=SEQ.+[0-9]+*$` 的含义如下:

`^` 字符表示行的开头,后面是`=SEQ.+[0-9]+*$`,这表示 tac 命令查找以 “=SEQ” 开头且后跟任意数字序列(由 `[0-9]+` 表示)的行,最后是任意字符(由`.*$`表示)。

就像往常一样,我们把所有的输出都通过管道传递给 `less` 命令。

现在我们的文件以相反的顺序显示,每个 “=SEQ” 标签行都在其三行十六进制数据之前。 每个数据记录中,三行十六进制值的原始顺序也得到了保留。

我们可以简单地验证一下。 十六进制值的前三行(反转之前是最后三行)与我们之前记录的值相匹配:93、E7 和 B8,并且顺序一致。

对于一个命令行工具来说,这是一个非常强大的技巧。

每个工具都有其目的

在 Linux 世界中,即使是最简单的命令和实用程序也可能具有令人惊讶的强大功能。

简单实用的设计理念 做好一件事, 并易于与其他实用程序交互,产生了一些像 `tac` 这样看似奇怪的小命令。 乍一看,它可能有点奇怪,但是,一旦你了解了它的内在原理,你就可以利用意想不到的力量。

或者,正如另一种哲学所说,“不要因为蛇没有角就轻视它,谁知道它会不会变成龙呢?”