我希望从可能的大型日志文件(> 50..1000mb)中获取给定时间戳“t0”以来的最后一部分:
__________________
|1 xxx xxx ... |
|2 xxx ... | uninteresting part
|4 ... |
|... |
___|423 ... | ___ timestamp t0
|425 xxx ... |
|437 ... |
|... | <-- i want this part ( from t0 to EOF)
|__________________|
另外一个约束是我想用简单的bash命令来做这件事。一个简单的解决方案可能是:
awk '$1 > 423' file.log
但是这会用所有不感兴趣的行扫描整个文件。这是命令 tail ,但我可以给他他想要的最后一行我不知道的数量 - 我只知道时间戳。有没有办法从后面“晃动”并在第一个时间戳不匹配时停止处理?
答案 0 :(得分:4)
tac是你的朋友:
tac file.log | awk '{ if ($1 >= 423) print; else exit; }' | tac
tac将从最后一行开始转储文件的每一行,然后转到文件的开头。做一次得到你想要的线,然后再做一次来修理他们的订单。
答案 1 :(得分:1)
如果我理解正确,你只需要从时间戳regexp到文件末尾的n行。
请不要说你的大文件是这样的:
~$ cat > file << EOF
rubish
n lines of rubish
more rubish
timestamp regexp
interesting
n interesting lines
interesting
end of file
EOF
如果您能够获得正在寻找的时间戳的可行正则表达式,您可以使用sed获得所需的部分:
~$ sed -n '/timestamp regexp/,$ {p}' file
timestamp regexp
interesting
n interesting lines
interesting
end of file
答案 2 :(得分:1)
使用标准的Unix命令,除了扫描整个文件之外,没有什么可以做的。如果你编写自己的程序,你可以对文件进行二进制搜索:
如果时间戳是纯数字,您甚至可以使用线性插值而不是纯二进制搜索进行搜索;如果邮票更复杂,它可能不值得额外编码,但这取决于你需要多长时间。
事实上,除非你要做很多事情并且可以证明性能是一个问题,否则我会选择简单的awk
解决方案。
答案 3 :(得分:0)
你可以轮询,直到你点击“423”。只是一个假设的例子(未经测试)
n=100 # number of lines you want to go back
while true
do
if tail -$n file | grep -q "423" ;then
tail -$n file | awk '$1>423'
break
else
((n+=100)) # increment every 100 lines
fi
done