I have two big files (6GB each). They are unsorted, with linefeeds (\n
) as separators. How can I diff them? It should take under 24h.
3 Answers
The most obvious answer is just to use the diff command and it is probably a good idea to add the --speed-large-files parameter to it.
diff --speed-large-files a.file b.file
You mention unsorted files so maybe you need to sort the files first
sort a.file > a.file.sorted
sort b.file > b.file.sorted
diff --speed-large-files a.file.sorted b.file.sorted
you could save creating an extra output file by piping the 2nd sort output direct into diff
sort a.file > a.file.sorted
sort b.file | diff --speed-large-files a.file.sorted -
Obviously these will run best on a system with plenty of available memory and you will likely need plenty of free disk space too.
It wasn't clear from your question whether you have tried these before. If so then it would be helpful to know what went wrong (took too long etc.). I have always found that the stock sort and diff commands tend to do at least as well as custom commands unless there are some very domain specific properties of the files that make it possible to do things differently.
-
2+1. You can omit all temporary files with named pipes. Use
mkfifo
to create[ab].file.sorted
before using them as output forsort
. Put bothsort
s with&
in the background and use the both piped as filenames for diff.– krissiSep 16, 2010 at 11:45 -
15@krissi You can also accomplish the same effect using this syntax:
diff <(command 1) <(command 2)
Sep 16, 2010 at 14:12 -
Thanks worked. I needed a couple of GB of memory thought but a 16GB Amazon EC2 instance fixed it :) Sep 16, 2010 at 15:28
-
7If someone like me wonders why
<(cmd1) <(cmd2)
syntax works (as it sounds like redirecting standard input twice!), tryecho hello <(cmd1) <(cmd2)
. You'll see something likehello /dev/fd/63 /dev/fd/62
which suddenly makes it clear ;)– alexSep 16, 2010 at 19:53 -
4In my experience, the
--speed-large-files
option does not help if you do not have enough RAM. Also, pre-sorting is not helpful if you have a multi-line record structure you wish to preserve. The options referred to above (by @unhammer) are interesting, but the output fromrdiff
andbsdiff
is rather binary. Installingbdiff
from the Heirloom Toolbox looks like a dauning task (requires Heirloom devtools, extinct header files, …). Is it really worth the effort? Are there other alternatives? Feb 2, 2015 at 17:33
Sorting the inputs and telling the diff
program it's inputs are sorted would provide a massive speed up. I don't know of any diff
with an option like that but comm
assumes sorted input and will be much quicker if it does enough for your purposes.
-
3
comm
worked great for this, never heard of it before but apparently its in coreutils. Nov 16, 2019 at 6:14
The bdiff
tool can work on unsorted files much larger than the computer's RAM.
Use these steps once, to download and compile bdiff
before using it the first time:
wget https://github.com/Arkanosis/Arkonf/raw/master/tools-src/bdiff.c && \
gcc -Wformat=0 -Wno-long-long bdiff.c -o bdiff && \
rm bdiff.c
To run bdiff
and compare 2 files:
./bdiff a.file b.file
You might find it helpful to redirect the bdiff
output to a file.
Thanks to @unhammer for the suggestion and the link to the Git repository.