菜鸟科技网

Linux tac命令如何反向输出文本行?

什么是 tac 命令?

tac 命令是 cat 命令的“反向”版本,它的名字就是 cat 的倒写。

Linux tac命令如何反向输出文本行?-图1
(图片来源网络,侵删)
  • cat (Concatenate): 从上到下按行显示文件内容。
  • tac: 从下到上按行显示文件内容,即逆序输出文件的每一行。

cat 是 "catenate"(连接)的缩写,而 tac 的名字则是一个巧妙的双关语,暗示了它与 cat 的相反行为。

基本语法

tac [选项]... [文件]...
  • [选项]...: 可选的命令行参数,用于改变 tac 的行为。
  • [文件]...: 一个或多个要处理的文件,如果没有指定文件,或者文件名为 ,则从标准输入读取。

常用选项

tac 的选项比 cat 少很多,因为它主要用于简单的逆序输出。

选项 全称 描述
-b, --before before 在分隔符之前而不是之后附加内容,主要用于处理多字节字符的分隔符。
-r, --regex regex 将分隔符解释为正则表达式
--help help 显示帮助信息并退出。
--version version 显示版本信息并退出。

重要提示: tac 默认使用换行符 \n 作为行分隔符,这意味着它只是将行的顺序颠倒,而不会颠倒行内的字符顺序。

使用示例

我们首先创建一个示例文件 example.txt如下:

Linux tac命令如何反向输出文本行?-图2
(图片来源网络,侵删)
$ cat > example.txt
Line 1: This is the first line.
Line 2: This is the second line.
Line 3: This is the third line.
Line 4: This is the fourth line.
^C (按 Ctrl+C 结束输入)

示例 1:基本用法 - 逆序显示文件内容

这是 tac 最核心的功能,它会从文件的最后一行开始,向上打印到第一行。

$ tac example.txt
Line 4: This is the fourth line.
Line 3: This is the third line.
Line 2: This is the second line.
Line 1: This is the first line.

示例 2:处理多个文件

如果提供多个文件,tac 会按顺序逆序处理每个文件。

首先创建第二个文件 another.txt

$ echo "File A, Line 1" > another.txt
$ echo "File A, Line 2" >> another.txt

现在使用 tac 处理两个文件:

Linux tac命令如何反向输出文本行?-图3
(图片来源网络,侵删)
$ tac example.txt another.txt
File A, Line 2
File A, Line 1
Line 4: This is the fourth line.
Line 3: This is the third line.
Line 2: This is the second line.
Line 1: This is the first line.

可以看到,another.txt 的内容被逆序输出,然后才是 example.txt 的逆序内容。

示例 3:从标准输入读取

tac 可以像 cat 一样,通过管道接收其他命令的输出。

$ cat example.txt | tac
Line 4: This is the fourth line.
Line 3: This is the third line.
Line 2: This is the second line.
Line 1: This is the first line.

这与直接在文件上使用 tac 效果相同。

示例 4:使用 -r 选项(正则表达式分隔符)

tac 默认只识别换行符 \n 作为分隔符,假设你有一个文件,其中用 作为分隔符,但你希望以 为单位进行逆序。

创建一个新文件 separator.txt

$ cat > separator.txt
Section 1
---
Section 2
---
Section 3

不使用 -r 选项: tac 会把每一行都看作一个独立的行,然后逆序它们。

$ tac separator.txt
Section 3
---
Section 2
---
Section 1

这显然不是我们想要的结果。

使用 -r 选项: 我们将分隔符 定义为一个正则表达式。

$ tac -r -s '---' separator.txt
Section 3
---
Section 2
---
Section 1

等等,看起来结果一样? 让我们再仔细看看,哦,tac 在处理时,会先将文件按 分割成几个“块”,然后逆序这些“块”,在这个简单的例子中,顺序看起来没变,因为每个块只有一行,让我们换一个更复杂的例子:

$ cat > complex.txt
Header
---
Part A, Line 1
Part A, Line 2
---
Part B, Line 1
Part B, Line 2
---
Footer

现在使用 -r 选项:

$ tac -r -s '---' complex.txt
Footer
---
Part B, Line 1
Part B, Line 2
---
Part A, Line 1
Part A, Line 2
---
Header

这次结果就非常清晰了:整个文件被 分成了几个大块,然后这些大块的顺序被完全颠倒了。

tac vs. rev

初学者常常会混淆 tacrev 命令,因为它们都和“反向”有关。

命令 功能 示例输入 hello world
tac 逆序行 (Reverse lines) world
hello
rev 逆序字符 (Reverse characters) dlrow olleh
  • tac按行倒着看。
  • rev按字符倒着看。

tac 的局限性

tac 的实现方式决定了它有一个重要的性能限制:它需要将整个文件读入内存才能进行逆序操作,这是因为文件存储在磁盘上是顺序的,要逆序输出,tac 必须先读取所有内容,找到行尾,然后反向构建输出。

对于非常大的文件(例如几十GB的日志文件),使用 tac 可能会导致内存耗尽(OOM)或系统变得非常缓慢。

替代方案:处理大文件

如果你需要逆序查看一个非常大的文件,tac 就不是最佳选择了,这时可以使用 tailawk 的组合。

方法:使用 tailawk

这个组合的原理是:tail 可以从文件末尾开始读取,awk 可以逐行处理。

# 语法
tail -n +1 文件名 | awk '{a[i++]=$0} END {for (j=i-1; j>=0; j--) print a[j]}'
# 示例
tail -n +1 example.txt | awk '{a[i++]=$0} END {for (j=i-1; j>=0; j--) print a[j]}'

命令解析:

  • tail -n +1 example.txt: tail 从文件的第一行开始读取到最后一行,并输出到标准输出,这相当于 cat,但在这里是为了与 awk 管道连接。
  • awk '{a[i++]=$0}': awk 逐行读取输入。$0 代表整行,a[i++]=$0 将每一行存入数组 a,索引 i 从 0 开始递增。
  • END {for (j=i-1; j>=0; j--) print a[j]}: awk 处理完所有行后(END 块),执行循环,循环从数组的最后一个索引 (i-1) 开始,反向遍历到 0,并打印出对应的行,从而实现了逆序。

这种方法比 tac 更节省内存,因为它不需要一次性将整个文件加载到内存中。

特性 tac tail + awk
功能 逆序输出文件的行 逆序输出文件的行
易用性 非常简单,一个命令即可 较复杂,需要组合命令
内存消耗 ,需要加载整个文件 ,逐行处理
适用场景 小文件,快速查看 大文件,避免内存问题

何时使用 tac 当你需要快速逆序查看一个小到中等大小的文件时,tac 是最直接、最方便的选择。

何时使用替代方案? 当你处理的文件非常大,可能会耗尽系统内存时,应该使用 tailawk 的组合,或者其他更专业的工具(如 perl 脚本)。

分享:
扫描分享到社交APP
上一篇
下一篇