J'ai un grand fichier XML (40 Go) que j'ai besoin de diviser en morceaux plus petits. Je travaille avec un espace limité, il y a donc un moyen de supprimer des lignes du fichier d'origine lorsque je les écris aux nouveaux fichiers? P>
Merci! P>
7 Réponses :
Je suis à peu près sûr qu'il y a, comme j'ai même été capable d'éditer / lire à partir des fichiers source des scripts, je suis exécuté, mais le plus gros problème serait probablement tout le changement qui serait fait si vous avez commencé. au début du fichier. D'autre part, si vous passez dans le fichier et enregistrez toutes les positions de départ des lignes, vous pouvez ensuite aller dans l'ordre inverse de la position pour copier les lignes; Une fois que cela est fait, vous pouvez revenir en arrière, prendre les nouveaux fichiers, un à la fois et (s'ils sont suffisamment petits), utilisez des readlines () pour générer une liste, inverser l'ordre de la liste, puis chercher au début. du fichier et écrasez les lignes dans leur ancien ordre avec les lignes dans leur nouvelle. p>
(vous tronquiez le fichier après avoir lu le premier bloc de lignes à partir de la fin à l'aide de la méthode Edit: Basé sur votre commentaire sur le point de passer les séparations aux étiquettes de fermeture appropriées, vous devrez probablement également développer un algorithme pour détecter de telles balises (peut-être à l'aide de la méthode code> code>), éventuellement utiliser une expression régulière. P> tronquate () code>, qui tronque toutes les données après la position du fichier actuel si elle est utilisée sans arguments sans arguments. de l'objet de fichier, supposant que vous utilisiez l'une des classes ou une sous-classe de l'une des classes du package io code> pour lire votre fichier. Vous devrez juste vous assurer que le fichier actuel la position finit au début de la dernière ligne à écrire dans un nouveau fichier.) P>
Si vous êtes sous Linux / UNIX, pourquoi ne pas utiliser la commande Split comme Ce gars fait? EDIT: Ensuite, utilisez CSplit . P> P>
Cela ne fonctionnerait pas comme j'ai un fichier XML. J'aurais besoin de chaque fichier pour être divisé à l'emplacement correct (après un enregistrement de compétition avec des balises de fermeture).
@Maulin. aïe ... fait un problème intéressant cependant
Si le temps n'est pas un facteur important (ou une usure de votre lecteur de disque): P>
Si Python ne vous donne pas ce niveau de contrôle, vous devrez peut-être plonger dans c. p>
Vous pouvez toujours analyser le fichier XML et écrire dire tous les 10000 éléments à son propre fichier. Regardez la section d'analyse progressive de ce lien. http://effbot.org/zone/element-iterparse.htm P >
Disons que vous voulez diviser le fichier en n morceaux, puis commencez simplement à lire à l'arrière du fichier (plus ou moins) et appelez à plusieurs reprises tronquage :
tronquer la taille du fichier. Si l'argument de taille optionnelle est présent, le fichier est tronqué (au plus) de cette taille. La taille correspond à la position actuelle. La position du fichier actuel n'est pas modifiée. ... p> BlockQuote>
import os import stat BUF_SIZE = 4096 size = os.stat("large_file")[stat.ST_SIZE] chunk_size = size // N # or simply set a fixed chunk size based on your free disk space c = 0 in_ = open("large_file", "r+") while size > 0: in_.seek(-min(size, chunk_size), 2) # now you have to find a safe place to split the file at somehow # just read forward until you found one ... old_pos = in_.tell() with open("small_chunk%2d" % (c, ), "w") as out: b = in_.read(BUF_SIZE) while len(b) > 0: out.write(b) b = in_.read(BUF_SIZE) in_.truncate(old_pos) size = old_pos c += 1
Merci pour toute la contribution. Je vais essayer certaines de vos suggestions ce soir.
Beau détail. Je ne fais pas assez de python pour pouvoir tirer quelque chose comme ça sur le dessus de ma tête.
Existe-t-il un moyen de tronquer le premier numéro X d'octets d'un fichier? Truncate (100) rendra le fichier au plus 100 octets, comment puis-je supprimer les 100 premiers octets du fichier?
Merci pour toute votre aide les gars. Je viens de sortir facilement et j'ai eu le script FTP chaque morceau tel qu'il a été fait à un serveur qui avait plus d'espace. Si j'avais plus de temps, j'essaierais une approche des Torstens
Le seul moyen de supprimer les octets du début du fichier est soit de l'écrire totalement neuf, soit de tout déplacer sur place, c'est-à-dire que lire l'octet 100, écrire sur 0, lire 101, écrire sur 1, et puis tronquer à la fin. . Depuis que vous devez le faire encore et encore, vous vous retrouvez avec O (n ^ 2).
C'est un temps d'acheter un nouveau disque dur! P>
Vous pouvez faire une sauvegarde avant d'essayer toutes les autres réponses et n'atteignez pas les données perdues :) p>
Voici mon script ...
import string
import os
from ftplib import FTP
# make ftp connection
ftp = FTP('server')
ftp.login('user', 'pwd')
ftp.cwd('/dir')
f1 = open('large_file.xml', 'r')
size = 0
split = False
count = 0
for line in f1:
if not split:
file = 'split_'+str(count)+'.xml'
f2 = open(file, 'w')
if count > 0:
f2.write('<?xml version="1.0"?>\n')
f2.write('<StartTag xmlns="http://www.blah/1.2.0">\n')
size = 0
count += 1
split = True
if size < 1073741824:
f2.write(line)
size += len(line)
elif str(line) == '</EndTag>\n':
f2.write(line)
f2.write('</EndEndTag>\n')
print('completed file %s' %str(count))
f2.close()
f2 = open(file, 'r')
print("ftp'ing file...")
ftp.storbinary('STOR ' + file, f2)
print('ftp done.')
split = False
f2.close()
os.remove(file)
else:
f2.write(line)
size += len(line)
Désolé, je n'obtiens pas ce que c'est à propos.
Corrigez-moi si je me trompe, mais il essaie de partitionner un très grand fichier en parties plus petites. Cependant, étant donné que le fichier est si grand, car il crée des partitions, il doit supprimer cette pièce du fichier d'origine pour économiser de l'espace.
Désolé si je n'étais pas clair. J'ai besoin de diviser un fichier XML de 40 Go en fichiers plus petits à l'aide de Python. Normalement, je voudrais juste lire dans le fichier et écrire dans un nouveau fichier jusqu'à ce que la limite de taille souhaitée ait été atteinte. Cette approche vous obligerait à avoir 80 Go d'espace disque dur. 40 pour le fichier d'origine et 40 autres pour les divisions de l'original. Je n'ai pas de 80 Go d'espace disque dur pour travailler. Il y a donc un moyen de supprimer les lignes du fichier d'origine, car ils sont écrits dans les nouveaux fichiers?
Un fichier XML de 40 Go est un fichier créé par une personne qui ne comprend pas ce que XML est pour. Je veux dire, vous ne pouvez même pas dire s'il est bien formé jusqu'à ce que vous lisiez à l'EOF.
Eh bien, pas trop mentionner, s'ils ont autant de données, ils pourraient probablement réduire la taille des 2 / 3ths à 3 / 4ths en utilisant un format binaire. (C'est juste un fichier beastly!)