45 command-line grep sed awk efficiency
比方说,我有一个非常大的文本文件(大约 10.000.000 行)。我需要grep从头开始并将结果保存到文件中。完成任务的最有效方法是什么?
cha*_*aos 47
tac /grep解决方案
tac file | grep whatever
Run Code Online (Sandbox Code Playgroud)
或者更有效一点:
grep whatever < <(tac file)
Run Code Online (Sandbox Code Playgroud)
500MB 文件的时间:
real 0m1.225s
user 0m1.164s
sys 0m0.516s
Run Code Online (Sandbox Code Playgroud)
sed/grep解决方案:
sed '1!G;h;$!d' | grep whatever
Run Code Online (Sandbox Code Playgroud)
500MB 文件的时间:10 多分钟后中止。
awk/grep解决方案:
awk '{x[NR]=$0}END{while (NR) print x[NR--]}' file | grep whatever
Run Code Online (Sandbox Code Playgroud)
500MB 文件的时间:
real 0m5.626s
user 0m4.964s
sys 0m1.420s
Run Code Online (Sandbox Code Playgroud)
perl/grep解决方案:
perl -e 'print reverse <>' file | grep whatever
Run Code Online (Sandbox Code Playgroud)
500MB 文件的时间:
real 0m3.551s
user 0m3.104s
sys 0m1.036s
Run Code Online (Sandbox Code Playgroud)
Ans*_*tel 17
此解决方案可能会有所帮助:
tac file_name | grep -e expression
Run Code Online (Sandbox Code Playgroud)
zza*_*per 10
一旦找到第一个匹配项,它就会退出:
tac hugeproduction.log | grep -m1 WhatImLookingFor
Run Code Online (Sandbox Code Playgroud)
下面给出了前两场比赛前后的 5 行:
tac hugeproduction.log | grep -m2 -A 5 -B 5 WhatImLookingFor
Run Code Online (Sandbox Code Playgroud)
请记住不要使用-i(不区分大小写),除非您必须这样做,否则会减慢 grep 的速度。
如果您知道要查找的确切字符串,请考虑fgrep(固定字符串)
tac hugeproduction.log | grep -F -m2 -A 5 -B 5 'ABC1234XYZ'
Run Code Online (Sandbox Code Playgroud)
如果文件真的很大,无法放入内存,我将Perl与File::ReadBackwards模块一起使用CPAN:
$ cat reverse-grep.pl
#!/usr/bin/perl
use strict;
use warnings;
use File::ReadBackwards;
my $pattern = shift;
my $rev = File::ReadBackwards->new(shift)
or die "$!";
while (defined($_ = $rev->readline)) {
print if /$pattern/;
}
$rev->close;
Run Code Online (Sandbox Code Playgroud)
然后:
$ ./reverse-grep.pl pattern file
Run Code Online (Sandbox Code Playgroud)