Différents deux gros fichiers texte

32

J'ai deux gros fichiers (6 Go chacun). Ils ne sont pas triés, avec des sauts de ligne ( \n) comme séparateurs. Comment puis-je les différencier? Cela devrait prendre moins de 24h.

jonasl
la source

Réponses:

45

La réponse la plus évidente consiste simplement à utiliser la commande diff et c'est probablement une bonne idée d'y ajouter le paramètre --speed-large-files.

diff --speed-large-files a.file b.file

Vous mentionnez des fichiers non triés, vous devrez peut-être d'abord trier les fichiers

sort a.file > a.file.sorted
sort b.file > b.file.sorted
diff --speed-large-files a.file.sorted b.file.sorted

vous pouvez enregistrer la création d'un fichier de sortie supplémentaire en canalisant la sortie du deuxième tri directement dans diff

sort a.file > a.file.sorted
sort b.file | diff --speed-large-files a.file.sorted -

Évidemment, ceux-ci fonctionneront mieux sur un système avec beaucoup de mémoire disponible et vous aurez probablement besoin de beaucoup d'espace disque libre aussi.

Votre question ne vous a pas permis de savoir si vous les avez déjà essayées auparavant. Si c'est le cas, il serait utile de savoir ce qui n'a pas fonctionné (a pris trop de temps, etc.). J'ai toujours constaté que les commandes stock sort et diff ont tendance à faire au moins aussi bien que les commandes personnalisées, sauf s'il existe des propriétés très spécifiques au domaine des fichiers qui permettent de faire les choses différemment.

Richm
la source
2
+1. Vous pouvez omettre tous les fichiers temporaires avec des canaux nommés. Utilisez mkfifopour créer [ab].file.sortedavant de les utiliser comme sortie pour sort. Mettez les deux sorts &en arrière-plan et utilisez les deux piped comme noms de fichiers pour diff.
krissi
15
@krissi Vous pouvez également obtenir le même effet en utilisant cette syntaxe:diff <(command 1) <(command 2)
Michael Mrozek
Merci a fonctionné. J'avais besoin de quelques Go de mémoire, mais une instance Amazon EC2 de 16 Go l'a corrigé :)
jonasl
7
Si quelqu'un comme moi se demande pourquoi la <(cmd1) <(cmd2)syntaxe fonctionne (car cela ressemble à rediriger deux fois l'entrée standard!), Essayez echo hello <(cmd1) <(cmd2). Vous verrez quelque chose comme ça hello /dev/fd/63 /dev/fd/62qui le rend tout à coup clair;)
alex
3
D'après mon expérience, l' --speed-large-filesoption n'aide pas si vous n'avez pas assez de RAM. De plus, le pré-tri n'est pas utile si vous souhaitez conserver une structure d'enregistrement sur plusieurs lignes. Les options mentionnées ci-dessus (par @unhammer) sont intéressantes, mais la sortie de rdiffet bsdiffest plutôt binaire. L'installation bdiffdepuis Heirloom Toolbox ressemble à une tâche ardue (nécessite des devtools Heirloom, des fichiers d'en-tête éteints,…). Vaut-il vraiment la peine? Existe-t-il d'autres alternatives?
Christian Pietsch
5

Trier les entrées et dire au diffprogramme que ses entrées sont triées fournirait une accélération massive. Je n'en connais aucune diffavec une option comme celle-ci, mais commsuppose une entrée triée et sera beaucoup plus rapide si elle en fait assez pour vos besoins.

Karl
la source
commtravaillé très bien pour cela, jamais entendu parler auparavant, mais apparemment c'est in coreutils.
theferrit32