I have two sorted files A and B where the size of A is much greater than B, e.g. A is 100GB while B is 50MB. I want to quickly determine if there are any lines in B that are contained in A, stopping once a match is made. I currently have a python script for this but it runs slowly when the process has to be repeated thousands of times for different B's.
|
|
||||
| show 1 more comment |
|
Using
At the moment, this will continue to execute the comm in the background, I'm having trouble finding the right |
|||
|
|
|
You can try AWK to parse the files. At first I was thinking to break up the larger file, or store A in mem and run through B comparing each line to the A in mem. However, I think AWK might be what you're looking for. http://www.linuxjournal.com/article/8913 is a primer http://forums.devshed.com/unix-help-35/compare-two-files-using-awk-or-sed-425150.html is talking about file compare. I'm not on a linux right now, or I'd try to test it out. gawk http://www.gnu.org/software/gawk/manual/html_node/index.html |
||||
|
|
|
If the files are sorted you may be able to get join(1) or combine(1) to work reasonably efficiently. Additionally, you may be able to cut down the problem size by using uniq(1) on the larger file A. This will boil it down to a set of distinct lines, which can then be compared against your list of B files. Another possibility would be to adapt your python script to do something like the following.
This will use up a large amount of memory if the number of distinct lines in your 'B' files is large, so it may or may not be practical. If you don't mind post-processing to eliminate false positives you could cut memory consumption at this stage by just storing the hash. A third way would be to load the whole lot into a database and do the join, but that incurs the overhead of importing the data, which may be too great. With appropriate indexes the actual matching query would be quite fast and could check against all B files at once, i.e.
|
||||
|
|
I guess this is not a well-known feature of grep, but you can pass multiple patterns through a single file by putting each on its own line. This is mostly useful in combination with I haven't benchmarked this, but I'd expect it to be about as fast as it gets without doing preprocessing on A. |
|||
|

comm -12 A B | wc -land see how fast that is (0 = no match, nonzero is matched lines). I don't see a way to get it to stop after one match though. – Kevin Nov 21 '11 at 19:37|head -n1, not sure if that'll actually stop the comm and return early though. Or, if you're using it interactively you could just watch the raw output and kill it if it prints a line. – Kevin Nov 21 '11 at 19:53command use afifoandheadto kill it for you at the first line. – Kevin Nov 21 '11 at 19:57fifoandheadas answer so I can test it, that makes two new commands for me in one question! – Hooked Nov 21 '11 at 20:17