3 votes

Comment modifier chaque ligne d'un fichier et écrire dans le fichier après chaque modification ?

J'ai un fichier qui est très volumineux. J'ai besoin de réorganiser quelque chose dans le fichier, mais le fichier est trop volumineux pour être chargé en mémoire. J'ai réfléchi à des moyens d'atteindre cet objectif et j'ai trouvé qu'il suffisait d'éditer le fichier ligne par ligne. Donc, ce que je dois faire, c'est lire le fichier, supprimer certaines colonnes, puis écrire le fichier. Comme je l'ai déjà mentionné, le fichier est très gros, donc je dois écrire le fichier au fur et à mesure que le script s'exécute. Je vais donner un exemple d'ensemble de données et le code que j'utilise.

Voici un exemple d'ensemble de données

{'CHROM': {0: 'chr1', 1: 'chr1'}, 'POS': {0: 10397, 1: 12719}, 'ID': {0: '.', 1: '.'}, 'REF': {0: 'CCCCTAA', 1: 'G'}, 'ALT': {0: 'C', 1: 'C'}, 'QUAL': {0: 943.64, 1: 255.34}, 'FILTER': {0: 'VQSRTrancheINDEL99.00to100.00', 1: 'VQSRTrancheSNP99.80to100.00'}, 'INFO': {0: 'AC=1;AF=0.5;AN=2;BaseQRankSum=1.07;ClippingRankSum=-0.322;DP=11;ExcessHet=0.2139;FS=1.056;InbreedingCoeff=0.1828;MQ=27.81;MQ0=0;MQRankSum=1.59;NEGATIVE_TRAIN_SITE;QD=25.5;ReadPosRankSum=0.572;SOR=0.922;VQSLOD=-2.735;culprit=DP', 1: 'AC=1;AF=0.5;AN=2;BaseQRankSum=-0.922;ClippingRankSum=-0.198;DP=7;ExcessHet=0.0067;FS=0;InbreedingCoeff=0.4331;MQ=24.5;MQ0=0;MQRankSum=-1.495;QD=17.02;ReadPosRankSum=1.5;SOR=3.126;VQSLOD=-28.96;culprit=MQ'}, 'FORMAT': {0: 'GT:AD:DP:GQ:PL', 1: 'GT:AB:AD:DP:GQ:PL'}, 'CGND-HDA-03201': {0: '0/1:5,6:11:99:224,0,156', 1: '0/1:0.29:2,5:7:42:126,0,42'}, 'CGND-HDA-03202': {0: '0/1:5,6:11:99:224,0,156', 1: '0/1:0.29:2,5:7:42:126,0,42'}}

Voici le code que j'utilise

n = 0
for line in open(input, "r+"):
    li=line.strip()
    if li.startswith("#"):
        n = n+1
    if not li.startswith("#"):
        test = li.split("\t")
        test2 = (f"{test[0]}\t{test[1]}\t{test[9:]}")
        with open("output.txt","w") as out:
            out.write(test2, sep='\t')

J'ai quelques problèmes ici

  1. la sortie contient sur une seule ligne, la dernière ligne qui a été lue. Par exemple, le fichier contient une ligne comme celle-ci

    chr1 1021791 ['0/1:0.56:22,17:39:99:414,0,623', '0/1:0.56:22,17:39:99:414,0,623']

  2. Je ne veux pas que la sortie ait un crochet. J'ai besoin que la sortie ressemble plus à ceci

    chr1 1021791 0/1:0.56:22,17:39:99:414,0,623 0/1:0.56:22,17:39:99:414,0,623

  3. Le fichier de sortie doit être délimité par des tabulations.

Existe-t-il un moyen d'écrire continuellement dans un fichier après l'édition de chaque ligne ?

Le fichier original contient # que je n'ai pas montré ici, donc la partie du script qui ignore les lignes avec # est nécessaire Je sais que cela peut facilement être fait en utilisant bash mais je cherche une solution en utilisant python.

0voto

Prakash Dahal Points 1138

Le séparateur doit être \n au lieu de \t pendant l'écriture dans le fichier. De même, l'ouverture du fichier dans w à l'intérieur du for remplace le contenu précédent du fichier.

import ast
n = 0
with open("output.txt","w") as out:
    for line in open(input, "r+"):
        li=line.strip()
        if li.startswith("#"):
            n = n+1
        elif not li.startswith("#"):
            test = li.split("\t")
            new_test = ast.literal_eval(str(test[9:]))
            test2 = (f"{test[0]}\t{test[1]}\t{new_test[0]}\t{new_test[1]}\n")       
            out.write(test2)

0voto

the_one_neuron Points 317

La solution de Prakash Dahal fonctionne très bien. Après avoir joué avec les données un peu plus, j'ai réalisé que test[9:] Il y aura probablement un grand nombre de valeurs extraites et je ne voudrais pas avoir à lister chacune des newvalue dans test2 = (f"{test[0]}\t{test[1]}\t{new_test[0]}\t{new_test[1]}\n")

Depuis new_test = test[9:] est une liste, je combine la liste pour en faire une chaîne délimitée par des tabulations. Cela donne le résultat global souhaité

n = 0
with open("output.txt","w") as out:
    for line in open(input, "r+"):
        li=line.strip()
        if li.startswith("#"):
         n = n+1
        elif not li.startswith("#"):
            test = li.split("\t")
            new_test = test[9:]
            new_test = '\t'.join(new_test)
            test2 = (f"{test[0]}\t{test[1]}\t{new_test}\n")       
            out.write(test2)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X