tac 命令的选项创建奇怪的输出

tac 命令的选项创建奇怪的输出

假设我有这个文件,只包含

a
b
c
b
a

在 BASH 中使用tac --separator=a file[在基于 Debian 的 Linux 上],我得到以下信息:

                  # empty line
                  # empty line
b
c
b
aacommand@prompt  # two a just before the prompt


问题:据我了解,--separator=a定义a标记字符串内的中断,而不是newline.这是正确的吗?

我已经尝试过使用其他字符串进行更多输入,但结果却很混乱。我认为其他选项都工作得很好:如果我使用,tac --before我首先会得到大约五比一的空行,但这就是应该发生的事情,对吧?

答案1

tac在其主要设计用途的情况下更容易理解,即当分隔符是记录终止符时,即分隔符出现在最后一条记录之后。它以相反的顺序打印记录(包括每个终止符)。

$ echo -n fooabara | tac -s a; echo
rabafooa

输入由三个记录(foobr)组成,每个记录后跟分隔符a;输出由三个记录(rbfoo)组成,每个记录后跟分隔符a

如果最后一条记录不以记录终止符结尾,则仍先打印它,不带记录分隔符。

$ echo -n fooabar | tac -s a; echo
rbafooa

最后一条记录r最终与倒数第二条记录连接在一起,b中间没有分隔符,因为最后一条记录的末尾没有分隔符。

由于换行符,您的输入看起来有点混乱。让我们用逗号而不是换行符来查看它:

$ echo -n a,b,c,b,a, | tac -s a; echo
,,b,c,b,aa

有三个输入记录:一个空记录(带有终止符a)、大记录,,b,c,b,(同样带有终止符)和一个,末尾未终止的记录。这些记录(每个记录都有终止符,除了最后一条没有终止符的记录)以相反的顺序打印。

您的困惑可能来自于期望“分隔符”是一个分隔符 - 但这是用词不当:它实际上是一个记录终止符。--before使其成为发起者。

答案2

以下示例可能有助于使用该--regex选项:

$ cat records 
---1---
1
2
3
---2
A
B
C
---3--
a
b
c
$ tac --before --regex --separator=^---[0-9]+-*$ records
---3--
a
b
c
---2
A
B
C
---1---
1
2
3

在此示例中,文件records包含多行记录,每行记录都以以 开头的行 ( ^...$) 开头---,后跟数字 ( [0-9]+) 和可选的减号序列 ( -*)。我们可以看到每条记录中的行顺序及其标题行都被保留。

我使用tac这种方式以相反的顺序显示日志文件条目,如 Twitter 等提要应用程序中所使用的那样。例如,仅以相反顺序打印最后两条记录:

tac --before --regex --separator=^---[0-9]+-*$ example \
 | awk '/^---[0-9]+-*$/ {c++} c>2 {exit}{print}'

相关内容