我希望从文件底部开始,直到开始。我尝试使用tac
并将其传递到我的awk
命令中,但速度非常慢(2GB文件为15秒)。与正常搜索相比(同一文件为3秒)。我还将awk
命令输入tail -n +1 | head -n 50
以在50个结果后停止。
tac
文件有更快捷的方法吗?或者至少从下往上开始搜索?
大局是创建一个带有参数(开始日期,结束日期,搜索条件)的python脚本,并使用它们搜索日期组织的日志文件。一次返回50个结果。
如果用户想要按降序搜索(最新日期到最早日期),我需要从头到尾阅读。
升序结果的示例命令('最旧到最新): (我使用find,因为是用户指定的参数,它可能会引用所有文件(* .txt))
find '/home/logs/' -type f -name 'log_file.txt' -exec cat {} \+ 2>&1| LANC=C fgrep 'Potato' | LC_ALL=C IGNORECASE=1 awk -v start="2018-03-04T03:45:00" -v stop="2018-03-05T16:24:59" 'BEGIN{IGNORECASE=1;} {line=$0; xz=" "; for(i=4;i<=NF;i++){xz=xz" "$i};} ($1>=start&&$1<=stop) && (tolower(xz) ~ /Potato/) {print line}' | tail -n +1 | head -n 50
tail -n +1 | head -n 50
将返回前50场比赛。
此命令大约需要3-4秒才能找到结果,但是如果我在tac中,则需要接近20秒。
答案 0 :(得分:2)
一切都取决于您所拥有的awk
代码,但我想到的一些解决方案是:
如果您打印每一行:
tac <file> | awk '(NR > 50){exit}{do-your-stuff}'
如果仅使用awk
tac <file> | awk '(c > 50){exit}
{ do-part-of stuff;
print foobar; c++;
do-remaining part}'
两个解决方案在前50行打印后终止awk
。这样您就不必处理完整的2GB文件。 50条打印线后的终止模仿了tail -n +1 | head -n 50
答案 1 :(得分:1)
好吧,如果你有内存,请在END
部分哈希记录并向后处理:
$ for i in {a..e} ; do echo $i ; done |
awk '{ a[NR]=$0 } # hash to a, NR as key
END { # in the end
for(i=NR;i>=1;i--) # process a in descending order
c++ # process
print c
}'
5
更新:我在上面测试了1 GB文件(36 M记录)。它在1分钟内进行了哈希计算并吸收了大约4.5 GB的内存。
答案 2 :(得分:1)
打开文件要快得多,并在文件结束前寻找一些金额。 Perl在这里很方便:
perl -Mautodie -se '
$size = -s $file;
$blocksize = 64000;
open $fh, "<", $file;
seek $fh, $size - $blocksize, 0;
read $fh, $data, $blocksize;
@lines = split "\n", $data;
# last 50 lines
print join "\n", reverse @lines[-51..-1];
' -- -file="filename"
我们可以在那里抛出一个循环,所以在它读取最后一个块之后,它可以寻找到最后减去2个块并读取一个块等。
但是如果你想从下到上处理整个巨大的文件,你将不得不期待它需要时间。