Ter*_*ior 19 grep awk database text
我有一个每天增长大约 200,000 行的文件,它都是由三行块组成的:
1358726575123 # key
Joseph Muller # name
carpenter # job
9973834728345
Andres Smith
student
7836472098652
Mariah Anthony
dentist
Run Code Online (Sandbox Code Playgroud)
现在,我有另一个文件,我从中提取了大约 10,000 个关键模式,例如1358726575123
. 然后我for
用这些模式运行一个循环,并且必须根据第一个文件检查它们。如果文件不包含此类模式,我会将模式保存在第三个文件中以供进一步处理:
for number in $(grep -o '[0-9]\{12\}' file2); do # finds about 10.000 keys
if ! grep -q ^$number$ file1; then # file1 is a huge file
printf "$number\n" >>file3 # we'll process file3 later
fi
done
Run Code Online (Sandbox Code Playgroud)
示例代码 grep 一个巨大的文件 10,000 次,我在一整天内大约每分钟运行一次这个循环。
由于巨大的文件不断增长,我该怎么做才能使这一切更快并节省一些 CPU?我想知道以某种方式通过其键(如果是,如何?)或使用 db 而不是纯文本对文件进行排序会有所帮助...
ang*_*gus 16
当然,问题在于您对大文件运行 grep 10,000 次。您应该只读取这两个文件一次。如果你想远离脚本语言,你可以这样做:
comm
在排序列表上运行以获取仅在第二个列表中的内容像这样的东西:
$ grep -o '^[0-9]\{12\}$' file1 | sort -u -o file1.sorted
$ grep -o '[0-9]\{12\}' file2 | sort -u -o file2.sorted
$ comm -13 file1.sorted file2.sorted > file3
Run Code Online (Sandbox Code Playgroud)
见man comm
。
如果您可以每天截断大文件(如日志文件),则可以保留已排序数字的缓存,而无需每次都对其进行完整解析。
Pet*_*r.O 11
这个答案基于potong ..awk
发布的答案。对于主文件中相同的600 万行和1 万个密钥,
它是方法(在我的系统上)的两倍......(现在更新为使用 FNR,无) comm
虽然awk
比您当前的系统快,并且会给您和您的计算机一些喘息空间,但请注意,当数据处理如您所描述的那样密集时,您将通过切换到专用数据库获得最佳整体结果;例如。SQLite、MySQL...
awk '{ if (/^[^0-9]/) { next } # Skip lines which do not hold key values
if (FNR==NR) { main[$0]=1 } # Process keys from file "mainfile"
else if (main[$0]==0) { keys[$0]=1 } # Process keys from file "keys"
} END { for(key in keys) print key }' \
"mainfile" "keys" >"keys.not-in-main"
Run Code Online (Sandbox Code Playgroud)
# For 6 million lines in "mainfile" and 10 thousand keys in "keys"
# The awk method
# time:
# real 0m14.495s
# user 0m14.457s
# sys 0m0.044s
# The comm method
# time:
# real 0m27.976s
# user 0m28.046s
# sys 0m0.104s
Run Code Online (Sandbox Code Playgroud)