Le Moyen le plus rapide pour Supprimer une Ligne de Gros Fichier en Python
Je suis en train de travailler avec un très grand (~11 GO) fichier texte sur un système Linux. Je suis en cours d'exécution à travers un programme qui est en train de vérifier le fichier d'erreurs. Une fois qu'une erreur est trouvée, j'ai besoin de corriger la ligne ou de supprimer la ligne complètement. Et puis répétez...
Finalement, une fois que je suis à l'aise avec le processus, je vais automatiser entièrement. Pour l'instant cependant, supposons que je suis en cours d'exécution à la main.
Quelle serait la manière la plus rapide (en termes de temps d'exécution) pour supprimer une ligne de ce fichier volumineux? J'ai pensé à le faire en Python...mais d'être ouvert à d'autres exemples. La ligne peut être n'importe où dans le fichier.
Si Python, assumer l'interface suivante:
def removeLine(filename, lineno):
Merci,
-aj
- L'utilisation de grep -v serait susceptible d'être plus rapide que l'utilisation de Python
- Qui ligne avez-vous supprimer? Comment allez-vous être en mesure de l'identifier? La réponse à ce qui pourrait faire une grande différence à la stratégie.
- Est une solution de script absolument nécessaire? Grande Visionneuse de Fichier Texte (swiftgear.com/ltfviewer/features.html) doit être capable de gérer le fichier et vous pouvez rechercher la bonne ligne à l'aide d'Expressions Régulières.
- Un bon éditeur de texte (par exemple, gvim) ne devrait pas avoir beaucoup de problèmes avec un texte plus long fichier. 11 GO n'est pas rare...
- Révisé la question de donner plus de détails sur l'exigence, merci.
- quelle solution proposeriez-vous dans grep?
- Byers - je obtenir le numéro de la ligne basé sur la sortie d'un autre programme. Il pourrait se produire n'importe où dans le fichier.
- l'utilisation de Linux, révisé à ma question. Merci.
- chat le fichier et le tuyau en à grep -v avec la chaîne de caractères / ligne que vous souhaitez ignorer cat fichier | grep -v "meh" > filteredFile Ici filteredFile ne comporte aucune ligne contenant "meh". Grep est généralement très efficace et donc peut vous donner beaucoup de l'amélioration de la performance sur une méthode similaire mis en œuvre en Python
- merci, mais je ne suis pas de décider de la ligne à supprimer basée sur la correspondance d'un motif. je sais déjà exactement numéro de la ligne à supprimer.
- AJ: sed est exactement ce dont vous avez besoin. Regardez les
d
de commande. - Le plus rapide serait de mettre à jour le fichier en place, en remplacement de la ligne avec un espace, est acceptable? puis
mmap
est le chemin à parcourir - Au lieu de répéter le processus, est-il possible de tout faire en une seule passe? Qui devrait être beaucoup plus efficace
- Au lieu de supprimer la ligne, créer un nouveau fichier pour les numéros de ligne des lignes supprimées, et de stocker le numéro de la ligne dans ce fichier. La prochaine fois que vous lisez le fichier, prétendent que la ligne supprimée n'est pas là.
Vous devez vous connecter pour publier un commentaire.
Vous pouvez avoir deux objets de fichier pour le même fichier en même temps (l'un pour la lecture, l'une pour l'écriture):
Modifier le fichier en place, la ligne incriminée est remplacé par des espaces de sorte que le reste du fichier n'a pas besoin d'être bousculés sur le disque. Vous pouvez également "fixer" la ligne à la place si le correctif n'est pas plus longue que la ligne de remplacement
Si l'autre programme peut être modifié à la sortie de la fileoffset au lieu du numéro de la ligne, vous pouvez assigner le décalage de p directement et de faire sans la boucle for
Autant que je sache, vous ne pouvez pas ouvrir un fichier txt avec python et supprimer une ligne. Vous devez faire un nouveau fichier et le déplacer tout, mais que la ligne à. Si vous connaissez le ligne, alors vous devez faire quelque chose comme ceci:
Vous pouvez bien sûr consulter le contenu de la ligne au lieu de déterminer si vous voulez le garder ou pas. Je vous recommande également que si vous avez toute une liste de lignes supprimées/modifiées pour faire toutes ces modifications dans un seul passage dans le fichier.
enumerate()
dans une boucle for à compter le nombre d'itérations, comme dans:for ind, line in enumerate(f):
Si les lignes sont de longueur variable, alors je ne crois pas qu'il y est un meilleur algorithme de lire le fichier ligne par ligne et par écrit de toutes les lignes, sauf celle(s) que vous ne souhaitez pas.
Vous pouvez identifier ces lignes en vérifiant certains critères, ou en gardant une liste de lignes de lecture et la suppression de l'écriture de la ligne(s) que vous ne souhaitez pas.
Si les lignes sont de longueur fixe et que vous voulez supprimer des numéros de ligne, alors vous pourriez être en mesure d'utiliser
seek
pour déplacer le pointeur de fichier... je doute que vous avez de la chance si.Mise à jour: la solution à l'aide de sed comme demandé par poster en commentaire.
Pour supprimer par exemple la deuxième ligne du fichier:
Utiliser le
-i
basculer à modifier en place. Avertissement: ceci est une opération destructrice. Lire l'aide de cette commande pour plus d'informations sur la façon de faire la sauvegarde automatiquement.Je pense qu'il y avait un peu le même si pas exactement le même type de question posée ici. La lecture (et l'écriture) ligne par ligne est lent, mais vous pouvez lire un gros morceau dans la mémoire à la fois, passer par cette ligne par ligne, de sauter des lignes, vous ne voulez pas, alors à écrire ce que d'un seul morceau dans un nouveau fichier. Répétez jusqu'à ce que fait. Enfin remplacer le fichier d'origine avec le nouveau fichier.
La chose à regarder dehors pour est lorsque vous lisez un morceau, vous devez traiter avec la dernière, potentiellement partielle de la ligne de vous lire, et d'ajouter que dans la partie suivante vous lire.
@OP, si vous pouvez utiliser awk, par exemple, en supposant que le numéro de ligne est de 10
Je vais donner deux solutions basées sur la recherche de facteur (numéro de ligne ou une chaîne de recherche):
Numéro de ligne
Chaîne