试图调试服务器的一个问题,我唯一的日志文件是一个20GB的日志文件(甚至没有时间戳!)为什么人们使用System.out.println()作为日志?在生产吗? !)

使用grep,我找到了我想要查看的文件区域,第347340107行。

除了做一些

head -<$LINENUM + 10> filename | tail -20 

... 这将需要头读取日志文件的前3.47亿行,是否有一个快速而简单的命令将行347340100 - 347340200(例如)转储到控制台?

我完全忘记了grep可以打印匹配前后的上下文…这很有效。谢谢!


当前回答

Use

x=`cat -n <file> | grep <match> | awk '{print $1}'`

在这里,您将获得发生匹配的行号。

现在可以使用下面的命令打印100行

awk -v var="$x" 'NR>=var && NR<=var+100{print}' <file>

或者你也可以使用“sed”

sed -n "${x},${x+100}p" <file>

其他回答

我很惊讶,只有另一个答案(由Ramana Reddy)建议在输出中添加行号。下面搜索所需的行号并为输出上色。

file=FILE
lineno=LINENO
wb="107"; bf="30;1"; rb="101"; yb="103"
cat -n ${file} | { GREP_COLORS="se=${wb};${bf}:cx=${wb};${bf}:ms=${rb};${bf}:sl=${yb};${bf}" grep --color -C 10 "^[[:space:]]\\+${lineno}[[:space:]]"; }

要通过<line#>显示<textfile>中的一行,只需这样做:

perl -wne 'print if $. == <line#>' <textfile>

如果你想用更强大的方法用正则表达式来显示一行范围——我不会说为什么grep是一个坏主意,这应该是相当明显的——这个简单的表达式将在一次传递中显示你的范围,这是你在处理~20GB文本文件时想要的:

perl -wne 'print if m/<regex1>/ .. m/<regex2>/' <filename>

(提示:如果你的regex中有/,使用类似m!<regex>!相反)

这将打印出<filename>,从匹配<regex1>的行开始,直到(并包括)匹配<regex2>的行。

不需要一个向导,就可以看到一些调整可以使它更加强大。

最后一点:perl,因为它是一种成熟的语言,有许多隐藏的增强来提高速度和性能。考虑到这一点,它成为这种操作的明显选择,因为它最初是为处理大型日志文件、文本、数据库等而开发的。

简单的perl!如果你想从文件中获得第1、3和5行,输入/etc/passwd:

perl -e 'while(<>){if(++$l~~[1,3,5]){print}}' < /etc/passwd

Sed还需要读取数据来计算行数。 唯一可能的快捷方式是文件中有上下文/顺序可以操作。例如,如果日志行前面有固定宽度的时间/日期等。 您可以使用look Unix实用程序在文件中查找特定的日期/时间

Use

x=`cat -n <file> | grep <match> | awk '{print $1}'`

在这里,您将获得发生匹配的行号。

现在可以使用下面的命令打印100行

awk -v var="$x" 'NR>=var && NR<=var+100{print}' <file>

或者你也可以使用“sed”

sed -n "${x},${x+100}p" <file>