如何只改变一个txt文件中的一列,而保留所有其他列,并尊重空格?

2024-06-17 11:54:54 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个有很多行的文件。为了安全起见,我只是c/p在某种意义上,给我的文件的形状。你知道吗


| Martini system from 2b97.pdb                 |
| 55601                                        |
|     1ALA     BB    1  13.904   5.512   1.259 |
|    12VAL     BB   12   4.199  35.292  21.353 |
|   112VAL    SCC  113   4.367   5.234  21.445 |
|  1113CYS     BB 1114   4.041   4.969  21.220 |
| 11113CYS    SCC11115   4.088  14.816  21.041 |
| 19293DEC      C55598  19.018   0.828   7.094 |
|   9.05570   9.05570  30.02670                |

我需要在最后一列加0.1个单位。你知道吗

因此,我的输出文件应该如下所示:


| Martini system from 2b97.pdb                 |
| 55601                                        |
|     1ALA     BB    1  13.904   5.512   1.359 |
|    12VAL     BB   12   4.199  35.292  21.453 |
|   112VAL    SCC  113   4.367   5.234  21.545 |
|  1113CYS     BB 1114   4.041   4.969  21.320 |
| 11113CYS    SCC11115   4.088  14.816  21.141 |
| 19293DEC      C55598  19.018   0.828   7.194 |
|   9.05570   9.05570  30.02670                |

最重要的是,我的输出文件应该有完全相同的空白,格式和数据类型。此文件中的所有内容都是字符串。你知道吗

如果不考虑空格、格式和数据类型,则无法使用输出文件在所需的程序中运行。你知道吗

以防万一,我不需要保留初始文件(尽管我认为这部分与我要添加的内容无关)。你知道吗

谢谢你的帮助。 我已经试过了,但是我的问题是我不能用python保持同样的形状。你知道吗


Tags: 文件from内容格式单位system空白pdb
3条回答

我还使用十进制数学和字符串切片。以下是我的版本:

from decimal import Decimal, InvalidOperation

def add_zero_point_one(data):
    new_data = []
    for l in data.split('\n'):
        try:
            d = Decimal(l[38:46]) + Decimal('0.1')
            l = l[:38] + str(d).rjust(8) + l[46:]
        except InvalidOperation:
            pass
        new_data.append(l)
    return '\n'.join(new_data)

这对提供的示例有效,但假设:

  1. 片38:46中的所有数据都是要递增的列数据
  2. 列宽是固定的

以下是我的完整工作示例:

from decimal import Decimal, InvalidOperation

data = '''| Martini system from 2b97.pdb                 |
| 55601                                        |
|     1ALA     BB    1  13.904   5.512   1.259 |
|    12VAL     BB   12   4.199  35.292  21.353 |
|   112VAL    SCC  113   4.367   5.234  21.445 |
|  1113CYS     BB 1114   4.041   4.969  21.220 |
| 11113CYS    SCC11115   4.088  14.816  21.041 |
| 19293DEC      C55598  19.018   0.828   7.094 |
|   9.05570   9.05570  30.02670                |'''


def add_zero_point_one(data):
    new_data = []
    for l in data.split('\n'):
        try:
            d = Decimal(l[38:46]) + Decimal('0.1')
            l = l[:38] + str(d).rjust(8) + l[46:]
        except InvalidOperation:
            pass
        new_data.append(l)
    return '\n'.join(new_data)


print(data)
print(add_zero_point_one(data))

类似于其他答案,但这里有另一个选择。字符串反转完成后,将字符串替换为right->;left。你知道吗

with open('in.txt', 'r') as fi, open('out.txt', 'w') as fo:
    fo.write(fi.readline())
    fo.write(fi.readline())

    for line in fi.readlines():
        try:
            old = line[-10:-3]
            new = '{:>7.3f}'.format(float(old) + 0.1)
            line = line[::-1].replace(old[::-1], new[::-1], 1)[::-1]
        except ValueError as _:
            pass
        finally:
            fo.write(line)

像另一个答案一样,我将使用字符串切片来获得最后一列,并使用字符串连接来重新组合行。但是,我会使用decimal.Decimal作为定点数学:

import fileinput
import decimal
import sys

files = ['x.txt']

for line in fileinput.input(files, inplace=True):
    number = line[38:46]
    try:
        number = decimal.Decimal(number)
        number += decimal.Decimal('.1')
        number = '{:8}'.format(number)
        line = line[:38] + number + line[46:]
    except decimal.InvalidOperation:
        pass
    sys.stdout.write(line)

相关问题 更多 >