假设我有这个文件,只包含
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
输入由三个记录(foo
、b
和r
)组成,每个记录后跟分隔符a
;输出由三个记录(r
、b
和foo
)组成,每个记录后跟分隔符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}'