对大量数据进行grepping的不同方法

时间:2016-08-25 12:24:38

标签: bash grep

所以我有一个huuuuge文件和一个我要从该文件中删除的大项目列表。 为了这个例子,让文件这样表示 -

seq 1 10000 > file.txt          #file.txt contains numbers from 1 to 10000
seq 1 5 10000 > list            #list contains every fifth number from 1 to 10000

我的问题是,这是一个最好的方法来查找对应于' list'来自' file.txt'

我试过两种方式 -

time while read i ; do grep -w "$i" file.txt ; done < list > output

那个命令花了 - 真正的0m1.300s

time grep -wf list file.txt > output

这个速度较慢,在实际0m1.402秒时钟。

有更好(更快)的方法吗?有没有一种我失踪的最佳方式?

3 个答案:

答案 0 :(得分:2)

你正在比较苹果和橘子

此命令会从file.txt

中的列表中获取单词
time for i in `cat list`; do grep -w "$i" file.txt ; done > output

此命令会从列表

中的file.txt中获取模式
time grep -f file.txt list > output

你需要修复一个文件作为要匹配的字符串的源,另一个文件作为匹配字符串的目标数据 - 也使用相同的grep选项,如-w或-F

听起来list是模式的来源,file.txt是目标数据文件 - 这是我原始调整命令的时间加上一个awk和两个sed解决方案 - sed解决方案的不同之处在于模式是否作为单独的sed给出命令或一个扩展的正则表达式

定时

one grep
real    0m0.016s
user    0m0.001s
sys     0m0.001s
2000 output1

loop grep
real    0m10.120s
user    0m0.060s
sys     0m0.212s
2000 output2

awk
real    0m0.022s
user    0m0.007s
sys     0m0.000s
2000 output3

sed
real    0m4.260s
user    0m4.211s
sys     0m0.022s
2000 output4

sed -r
real    0m0.144s
user    0m0.085s
sys     0m0.047s
2000 output5

脚本

n=10000
seq 1 $n >file.txt             
seq 1 5 $n >list               

echo "one grep"
time grep -Fw -f list file.txt > output1
wc -l output1

echo "loop grep"
time for i in `cat list`; do grep -Fw "$i" file.txt ; done > output2
wc -l output2

echo "awk"
time awk 'ARGIND==1 {list[$1]; next} $1 in list' list file.txt >output3
wc -l output3

echo "sed"
sed 's/^/\/^/;s/$/$\/p/' list >list.sed
time sed -n -f list.sed file.txt >output4
wc -l output4

echo "sed -r"
tr '\n' '|' <list|sed 's/^/\/^(/;s/|$/)$\/p/' >list.sedr
time sed -nr -f list.sedr file.txt >output5
wc -l output5

答案 1 :(得分:1)

您可以尝试awk

awk 'NR==FNR{a[$1];next} $1 in a' file.txt list

在我的系统中,awk比样本数据grep更快。

<强>测试

$ time grep -f file.txt list > out

real    0m1.231s
user    0m1.056s
sys     0m0.175s

$ time awk 'NR==FNR{a[$1];next} $1 in a' file.txt list > out1

real    0m0.068s
user    0m0.067s
sys     0m0.001s

答案 2 :(得分:0)

更快或更快,你在那里无用cat 为什么不呢?

grep -f list file.txt   # Aren't files meant other way

或者使用更多自定义的awk

awk 'NR==FNR{a[$1];next} $1 in a{print $1;next}' list file.txt