尾-f,但带有行号


21

我正在尝试查看在任意时间范围内在远程服务器上foo bar出现了多少次/var/log/foo.log,但是到目前为止我没有尝试过。

我已经有了一个计时器脚本,可以用来跟踪自开始拖尾以来已经有多长时间了/var/log/foo.log,现在我想要一种方法来判断foo bar拖尾输出中出现了多少次。

我搜索了google,但在搜索结果的前10页中没有发现任何相关信息。

这是我尝试过的令人沮丧的结果:

## works on local machine, but doesn't work as expected on remote
tail -f /var/log/foo.log | grep foo\ bar | sed '='

## works on local, but not remote
tail -f /var/log/foo.log | grep foo\ bar | cat -n -

##  works on local, but not remote
tail -f /var/log/foo.log | grep foo\ bar | awk -F'\n' '{printf "[%d]> ", NR; print $1}'

我什至试图编写一个类似sed的脚本tail -f,但是我对此没有限制。

注意

远程服务器正在运行较旧版本的coreutils,并且可以选择升级,但绝不是所需的解决方案。


2
用哪种方式不起作用?尝试--line-buffered选择grep。或者tail -f ... | awk '/foo bar/{print ++n, $0}'
斯特凡Chazelas

为什么它在遥控器上不起作用?示例:tail -f /var/log/log.log | awk '{ printf "[%d]> %s\n", NR+1 ,$0; fflush(stdout); }'

Answers:


29
tail -f | nl

对我有用,这是我首先想到的-也就是说,如果您确实想要从1开始编号的行,而不是要观看文件中的实际行号。grep如果需要,可以选择将其添加到适当的位置(之前或之后nl)。但是,请记住可能会发生缓冲。在我的特定情况下,grep具有--line-buffered选项,但会nl缓冲其输出,并且没有选项将其关闭。因此,该tail | nl | grep组合并不能很好地流动。

那就是

tail -f | grep -n pattern

也为我工作。编号再次从“尾部”的开头而不是整个日志文件的开头开始。


服务器上运行的grep版本没有-n选项。
2014年

但是,它确实有很长的选择--line-number:可行tail -f /var/log/foo.log | grep foo\ bar --line-number
Alexej Magura 2014年

1
很有意思-我还没有检查过POSIX,但是GNU grep手册页说:-n由POSIX指定
彼得2014年

16

我认为这更好。

less -N +F <filepath>

2
您能解释一下为什么您认为更好吗?
Navigatron 2015年

这是一个很大的修改,我要还原。
亚当·埃伯林

3
显示行号,以整个文件为参考。尾-f | nl显示行号,以tail的第一个输出为参考。
拉斐尔瓦莱

这非常方便,可以解决OP的标题,但不能解决他们的问题。他们想知道X在文件中出现多少次:P
Timmah

6

您还可以将输出通过管道传递到less,它具有行号功能,-N使您可以在日志中来回滚动。

$ tail -f /var/log/foo.log | less -N

  1 Jan 17 22:11:58 greeneggs fprintd[4323]: ** Message: entering main loop
  2 Jan 17 22:12:01 greeneggs su: (to root) saml on pts/5
  3 Jan 17 22:12:28 greeneggs fprintd[4323]: ** Message: No devices in use, exit
  4 Jan 17 22:12:56 greeneggs gnome-session[1876]: 22:12:56 | Git | personal_repo | Checking for remote changes...
  5 Jan 17 22:12:56 greeneggs gnome-session[1876]: 22:12:56 | Cmd | personal_repo | git rev-parse HEAD
  6 Jan 17 22:12:56 greeneggs gnome-session[1876]: 22:12:56 | Cmd | personal_repo | git ls-remote --heads --exit-code "ssh://sam@sparkleshare.jake      
  6 8us.org/home/sam/SparkleShare/personal_repo.git" master
  7 Jan 17 22:12:58 greeneggs gnome-session[1876]: X11 forwarding request failed on channel 1
  8 Jan 17 22:12:58 greeneggs gnome-session[1876]: 22:12:58 | Git | personal_repo | No remote changes, local+remote: 532213be48cce3b93cb177d409faa      
  8 03b71d0cfa5
  9 Jan 17 22:13:35 greeneggs gnome-session[1876]: 22:13:35 | ListenerTcp | Pinging tcp://notifications.sparkleshare.org:443/
 10 Jan 17 22:13:35 greeneggs gnome-session[1876]: 22:13:35 | ListenerTcp | Received pong from tcp://notifications.sparkleshare.org:443/

注意:注意输出。您可能会或可能不会喜欢此功能,但是它将花费很长的行并将其切碎,以便它们在下一行继续,但仍保持相同的相应行号。解析宽日志文件时,我发现此功能非常宝贵!您可以在第68行上看到此功能的效果。


这还不清楚。文件名在哪里指定?应该澄清一下,注意输出从文件名的最后10行开始从1开始编号,因为这是的默认行为tail。至于长行,则less使用来切换该行为-S
ILMostro_7 '16

2

要grep 仅在日志文件中以行号附带行,请执行以下操作:

{
  initial_lines=$(wc -l)
  tail -n +1 -f | awk -v NR="$initial_lines" '/pattern/{print NR": "$0}'
} < file.log

(与 mawk,您将要添加该-Winteractive选项以防止其输入(!)缓冲)。

wc -l读取已经存在的行并对其进行计数(换行符,这意味着即使最后一行还没有满,它仍然可以工作),然后tail -f剩下的(从wc停止读取的位置开始)并告诉awk它的行号是多少它看到的第一个。


选择l作为变量名使我斜着眼睛看着$ l,以为它是$1^^(但是据我所知(和100%的信任),您重读并看到了事实)。仅出于好奇:为了避免wc -l和之间的某些“竞争条件” tail -f(如果文件快速增长,可能会丢弃某些行,因此NR从错误的数字开始),是否可以跳过$l行?(-n在posix和gnu中,尾部有什么限制?)。也许有一个临时的中间文件?
奥利维尔·杜拉克

@OlivierDulac tail -n +1(从起始位置读取任何内容)解决了比赛条件问题。它将wc -l从终止的确切位置读取文件终止时不在文件中的行wc。因此,无论wc结束和tail开始之间写了多少行,NR都将具有正确的位置。如果您被告知tail要从相对于文件末尾的某个位置开始,那您就会遇到问题。
斯特凡Chazelas

哦,有趣的是:确实,数据在没有任何读取的情况下(在wc的末尾到头部开始之间)积累到了stdin中……我应该意识到这一点。谢谢。现在,我明白了为什么您使用“ <文件”了。像往常一样聪明:)
Olivier Dulac

1
@OlivierDulac,关于限制(不适用于tail -n +1此处),对于常规文件,大多数实现都没有一个,因为它们可以从头开始然后seek返回直到找到第n个换行符而不必存储多个buf内存中的数据。对于不可寻求的输入,您可能会遇到限制。POSIX要求实现至少能够存储10 x LINE_MAX字节(LINE_MAX至少为2048)。GNU尾部有没有内存以外限制AFAIK
斯特凡Chazelas

0

如果要从头开始编号,则需要grep -n应用于所有行。

 tail -f -n100000000 filename.log | grep -n '' 

如果您只想显示最后10个,我本以为您可以重新整理文件:

 tail -f -n100000000 filename.log | grep -n '' | tail -n10

第一个很方便,但是显示了太多的输出。我不知道第二个为什么不起作用。


尾巴没有“显示所有行”,因此我的100000000
Martin Cleaver

1
tail -n +1 -f从一开始就尾巴。
斯特凡Chazelas

1
第二个行不通,因为最右边的tail行在看到输入的最后一行之前不会输出任何内容(它怎么知道最后一行的第10行?)这将永远tail -f不会停止发生。
斯特凡Chazelas

-1

cat -n [filename] | tail如果您正在寻找该命令,该命令将快速计数并显示最新记录。

-f开关使它一直保持到退出为止-听起来确实不适合您的情况,或者是多余的。

wc -l [filename] 将获得目标中的行数

wc -l [filenameprefix]* 将计算所有与模式匹配的文件中的所有行,甚至在最后报告总计。

更完整的细节可以产生更完整的响应。


-1

这是参数n--lines(使用稍有不同的方式,请参见下文):

$ tail -f -n 25 /path/to/file.txt

$ tail -f --lines=25 /path/to/file.txt

另请参阅帮助:

$ tail --help

1
OP需要行号,而不是行号。
robbat2
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.