尝试调试服务器的问题,我唯一的日志文件是20GB的日志文件(没有时间戳!为什么人们使用System.out.println()
作为日志记录?在生产中?!)
使用grep,我找到了一个我想看一下的文件区域,第347340107行。
除了做
之外的事情head -<$LINENUM + 10> filename | tail -20
...这需要head
来读取日志文件的前347万行,是否有一个快速简单的命令可以将行347340100 - 347340200(例如)转储到控制台?< / p>
更新我完全忘记了grep可以打印匹配的上下文...这很有效。谢谢!
答案 0 :(得分:354)
如果您知道行号,我发现了另外两个solutions,但没有其他内容(没有grep可能):
假设你需要20到40行,
sed -n '20,40p;41q' file_name
或
awk 'FNR>=20 && FNR<=40' file_name
答案 1 :(得分:101)
# print line number 52
sed -n '52p' # method 1
sed '52!d' # method 2
sed '52q;d' # method 3, efficient on large files
方法3对大文件有效
显示特定行的最快方式
答案 2 :(得分:68)
使用GNU-grep你可以说
grep --context=10 ...
答案 3 :(得分:23)
没有,文件不是行可寻址的。
在文本文件中找不到行 n 的开头没有固定时间方法。您必须流式传输文件并计算换行符。
使用最简单/最快的工具来完成这项工作。对我而言,使用head
会使 比grep
更有意义,因为后者更复杂。我不是说“grep
很慢”,实际上并非如此,但如果它比head
更快,我会感到惊讶。这基本上是head
中的一个错误。
答案 4 :(得分:19)
怎么样:
tail -n +347340107 filename | head -n 100
我没有测试它,但我认为这样可行。
答案 5 :(得分:12)
我首先将文件分成几个较小的文件,如
$ split --lines=50000 /path/to/large/file /path/to/output/file/prefix
然后grep生成的文件。
答案 6 :(得分:11)
我更喜欢进入less
和
:43210
做同样的事情和那样的东西。
更好:点击 v 开始编辑(当然是在vim中!),在那个位置。现在,请注意vim
具有相同的键绑定!
答案 7 :(得分:8)
你可以使用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
是退出编辑器的命令(添加!
以强行退出,例如-scq!
)。答案 8 :(得分:5)
获取确认
ack --lines = start-end filename
答案 9 :(得分:4)
sed也需要读取数据以计算行数。 快捷方式可行的唯一方法是在文件中进行上下文/顺序操作。例如,如果前面有固定宽度时间/日期等的日志行。 您可以使用外观 unix实用程序对特定日期/时间的文件进行二进制搜索
答案 10 :(得分:3)
如果您要读取的行号是100
1528773495.945011914 : 8=FIX.4.2 35=0 108=20 49=36593 56=NSE 10=000
答案 11 :(得分:3)
使用
x=`cat -n <file> | grep <match> | awk '{print $1}'`
在这里,您将获得匹配发生的行号。
现在您可以使用以下命令打印100行
awk -v var="$x" 'NR>=var && NR<=var+100{print}' <file>
或者您可以使用&#34; sed&#34;以及
sed -n "${x},${x+100}p" <file>
答案 12 :(得分:2)
以Sklivvz为基础&#39;回答,这是一个可以放在.bash_aliases
文件中的好函数。从文件前面打印东西时,它对大文件很有效。
function middle()
{
startidx=$1
len=$2
endidx=$(($startidx+$len))
filename=$3
awk "FNR>=${startidx} && FNR<=${endidx} { print NR\" \"\$0 }; FNR>${endidx} { print \"END HERE\"; exit }" $filename
}
答案 13 :(得分:2)
使用sed -e '1,N d; M q'
,您将打印N + 1到M行。这可能比grep -C
好一点,因为它不会尝试将线条与模式匹配。
答案 14 :(得分:1)
要显示<textfile>
的{{1}}行,请执行以下操作:
<line#>
如果你想要一种更强大的方式来显示带有正则表达式的一系列线条 - 我不会说为什么grep对于这样做是个坏主意,它应该是相当明显的 - 这个简单的表达式将显示你在处理~20GB文本文件时所需要的一次通过你的范围:
perl -wne 'print if $. == <line#>' <textfile>
(提示:如果您的正则表达式中包含perl -wne 'print if m/<regex1>/ .. m/<regex2>/' <filename>
,请使用类似/
的内容)
这将打印m!<regex>!
从与<filename>
匹配的行开始,直至(包括)与<regex1>
匹配的行。
它没有一个向导来看看一些调整如何使它更强大。
最后一件事:perl,因为它是一种成熟的语言,有许多隐藏的增强功能,以支持速度和性能。考虑到这一点,它使它成为这种操作的明显选择,因为它最初是为处理大型日志文件,文本,数据库等而开发的。
答案 15 :(得分:0)
您可以尝试以下命令:
egrep -n "*" <filename> | egrep "<line number>"
答案 16 :(得分:0)
perl很容易!如果你想从文件中获取第1,3和5行,请说/ etc / passwd:
perl -e 'while(<>){if(++$l~~[1,3,5]){print}}' < /etc/passwd
答案 17 :(得分:0)
我很惊讶只有另一个答案(由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:]]"; }