web-dev-qa-db-fra.com

Triez le contenu d'un fichier texte extrêmement volumineux (800 Go) sous Windows

J'ai un fichier text avec un mot dans chaque ligne, la taille du fichier est de 800 Go. Je dois trier les mots par ordre alphabétique.

J'ai essayé d'utiliser le programme Windows sort en utilisant:

sort.exe input.txt /o output.txt

ce qui donne l'erreur: Pas assez de mémoire principale pour terminer le tri.

J'ai 32 Go deRAMdonc quand j'essaie de spécifier 10 Go de mémoire pour le tri en utilisant:

sort.exe input.txt /o output.txt /M 10000000

Je reçois:

Avertissement: la taille de mémoire spécifiée est réduite à la mémoire de pagination disponible.

L'enregistrement d'entrée dépasse la longueur maximale. Spécifiez un maximum plus grand.

Quelles sont mes options?

23
MaYaN

Quelles sont mes options?

Essayez Freeware Utilitaire de tri en ligne de commande CMSort .

Il utilise plusieurs fichiers temporaires, puis les fusionne à la fin.

CMsort lit les enregistrements d'un fichier d'entrée jusqu'à ce que la mémoire ajustée soit atteinte. Ensuite, les enregistrements sont triés et écrits dans un fichier temporaire. Cela sera répété jusqu'à ce que tous les enregistrements soient traités. Enfin, tous les fichiers temporaires sont fusionnés dans le fichier de sortie. Si la mémoire disponible est suffisante, aucun fichier temporaire n'est écrit et aucune fusion n'est nécessaire.

Un utilisateur indique qu'il a trié un fichier de 130 000 000 octets.

Si vous souhaitez modifier vous-même du code, il y a aussi Tri des fichiers texte volumineux - CodeProject - "Algorithme de tri des lignes dans les fichiers texte dont la taille dépasse la mémoire disponible"

15
DavidPostill

Une autre option consiste à charger le fichier dans une base de données. E.G MySQL et MySQL Workbench.
Les bases de données sont des candidats parfaits pour travailler avec des fichiers volumineux

Si votre fichier d'entrée ne contient que des mots séparés par une nouvelle ligne, cela ne devrait pas être trop difficile.

Après avoir installé la base de données et MySQL Workbench, voici ce que vous devez faire.
Créez d’abord le schéma (cela suppose que les mots ne seront pas plus longs que 255 caractères, bien que vous puissiez le modifier en augmentant la valeur de l’argument). La première colonne "idwords" est une clé primaire.

CREATE SCHEMA `tmp` ;

CREATE TABLE `tmp`.`words` (
  `idwords` INT NOT NULL AUTO_INCREMENT,
  `mywords` VARCHAR(255) NULL,
  PRIMARY KEY (`idwords`));

Deuxièmement, importez les données: Par exemple, cela importera tous les mots du tableau (cette étape peut prendre un certain temps. Je vous conseillerais de commencer par un test avec un petit fichier de mots. Une fois que vous êtes certain que le format est le même. le plus grand (tronquez la table .. IE Effacez-le et chargez le jeu de données complet).

LOAD DATA LOCAL INFILE "C:\\words.txt" INTO TABLE tmp.words
LINES TERMINATED BY '\r\n'
(mywords);


Ce lien peut vous aider à choisir le bon format pour le chargement. https://dev.mysql.com/doc/refman/5.7/en/load-data.html
E.G Si vous deviez ignorer la première ligne, procédez comme suit.

LOAD DATA LOCAL INFILE "H:\\words.txt" INTO TABLE tmp.words
-- FIELDS TERMINATED BY ','
LINES TERMINATED BY '\r\n'
IGNORE 1 LINES
(mywords);

Enfin, enregistrez le fichier trié. Cela peut prendre un certain temps, cela dépend aussi de votre ordinateur.

SELECT tmp.words.mywords
FROM tmp.words
order by tmp.words.mywords asc
INTO OUTFILE 'C:\\sorted_words.csv';

Vous pouvez également rechercher les données à votre guise. E.G Ceci vous donnera les 50 premiers mots dans l'ordre croissant (à partir du 0ème mot ou du premier mot).

SELECT tmp.words.mywords
FROM tmp.words
order by tmp.words.mywords asc
LIMIT 0, 50 ;

Bonne chance
Pete

23
Peter H

sort

Il existe de nombreux algorithmes utilisés pour trier les fichiers ordonnés et non ordonnés. [ 1 ].
Comme tous ces algorithmes sont déjà implémentés, choisissez un programme déjà testé.

Dans coreutils} _ (sous Linux mais disponible aussi pour Windows [ 2 ]), il existe la commande sort capable de s’exécuter en parallèle sous des processeurs multicœurs: c’est généralement suffisant.

Si votre fichier est si énorme vous pouvez contribuer au fractionnement du traitement (split -l), le fichier en morceaux, éventuellement en utilisant l’option parallèle (--parallel), et en triant le résultat obtenu morceaux commandés avec l'option -m (tri par fusion _).
L’un des nombreux moyens de le faire est expliqué ici (fichier fractionné, commande de morceaux uniques, fusion de morceaux ordonnés, suppression de fichiers temporaires).

Notes:

  • Dans Windows 10, il existe ce que l'on appelle le sous-système Windows pour Linux, dans lequel tous les exemples de Linux sembleront plus naturels.
  • Le tri avec différents algorithmes a différents temps d’exécution qui s’échelonnent en fonction du nombre d’entrées de données à trier (O (nm), O (nlogn) ...).
  • L'efficacité de l'algorithme dépend de l'ordre déjà présent dans le fichier d'origine.
    (Par exemple, un type de bulle est l'algorithme le plus rapide pour un fichier déjà commandé - exactement N -, mais il n'est pas efficace dans les autres cas).
5
Hastur

Pour offrir une solution alternative à Peter H, il existe un programme q qui autorise les commandes de style SQL sur des fichiers texte. La commande ci-dessous ferait la même chose (exécutez-la à partir de l'invite de commande dans le même répertoire que le fichier), sans avoir à installer SQL Workbench ni à créer des tables.

q "select * from words.txt order by c1"

c1 est un raccourci pour la colonne 1.

Vous pouvez exclure les mots en double avec

q "select distinct c1 from words.txt order by c1"

et envoyer la sortie dans un autre fichier

q "select distinct c1 from words.txt order by c1" > sorted.txt
0
Brian