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

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

除了做一些

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

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

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


当前回答

我更喜欢更少的

输入50%到文件的一半, 43210G转到43210行 :43210来做同样的事情

诸如此类。

更好的方法是:点击v以在该位置开始编辑(当然是在vim中!)现在,请注意vim具有相同的键绑定!

其他回答

得到证实

Ubuntu/Debian 安装:

$ sudo apt-get install ack-grep

然后运行:

$ ack --lines=$START-$END filename

例子:

$ ack --lines=10-20 filename

来自$ man ack:

--lines=NUM
    Only print line NUM of each file. Multiple lines can be given with multiple --lines options or as a comma separated list (--lines=3,5,7). --lines=4-7 also works. 
    The lines are always output in ascending order, no matter the order given on the command line.

你可以使用ex命令,一个标准的Unix编辑器(现在是Vim的一部分),例如。

显示单行(例如第二行): Ex +2p -scq file.txt 对应的sed语法:sed -n '2p' file.txt 行范围(例如2-5行): Ex +2,5p -scq file.txt Sed语法:Sed -n '2,5p' file.txt 从给定的行到末尾(例如,第5行到文件末尾): Ex +5,p -scq file.txt Sed语法:Sed -n '2,$p' file.txt 多行范围(例如2-4行和6-8行): Ex +2,4p +6,8p -scq file.txt Sed语法:Sed -n '2,4p;6,8p' file.txt

以上命令可以用下面的测试文件进行测试:

seq 1 20 > file.txt

解释:

+或-c后跟命令-读取文件后执行(vi/vim)命令, -s -静默模式,也使用当前终端作为默认输出, Q后面加-c是退出编辑器的命令(add !强制退出,例如-scq!)。

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

用sed -e '1,N d;M q'你将打印从N+1到M的行,这可能比grep -C更好一点,因为它不会尝试将行与模式匹配。

你可以试试这个命令:

egrep -n "*" <filename> | egrep "<line number>"