簡體   English   中英

如何編輯文件的每一行並在每次編輯后寫入文件

[英]How to edit each line of file and write to file after each edit

我有一個非常大的文件。 我需要重新排列文件中的某些內容,但文件太大而無法加載到內存中。 我正在考慮實現這個目標的方法,我想到的只是逐行編輯文件。 所以我需要做的是讀取文件,刪除某些列,然后寫入文件。 正如我之前提到的,文件非常大,所以我需要在腳本運行時編寫文件。 我將給出一個示例數據集和我正在使用的代碼

這是一個示例數據集

{'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'}}

這是我正在使用的代碼

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')

我這里有一些問題

  1. 輸出包含在一行中,即讀取的最后一行。 例如,該文件包含這樣的一行

    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. 我不希望輸出有任何括號。 我需要輸出看起來更像這樣

    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. 我需要輸出文件以制表符分隔

有沒有辦法在編輯每一行后連續寫入文件?

原始文件確實包含我沒有在此處顯示的# ,因此需要忽略帶有#的行的腳本部分我知道這可以使用 bash 輕松完成,但我正在尋找使用 python 的解決方案。

寫入文件時,分隔符應該是\\n而不是\\t for循環內以w模式打開文件也會覆蓋文件的先前內容。

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)

Prakash Dahal 解決方案效果很好。 與所述數據多一點玩后,我意識到, test[9:]將可能是大量提取的值的,所以我不希望有列出每個的newvalue的在test2 = (f"{test[0]}\\t{test[1]}\\t{new_test[0]}\\t{new_test[1]}\\n")

由於new_test = test[9:]是一個列表,我將列表組合成一個制表符分隔的字符串。 這導致總體所需的輸出

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)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM