如何仅更改txt文件中的一列,使其他所有内容保持不变并遵守空格?

时间:2018-06-29 01:54:07

标签: python python-3.x pandas

我有一个包含很多行的文件。为了安全起见,从某种意义上说,我只是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                |

最重要的是,我的输出文件应具有完全相同的空格,格式和dtype。此文件中的所有内容都是字符串。

如果不遵守空格,格式和dtype,则无法使用输出文件在所需程序中运行。

以防万一,我不需要保留初始文件(尽管我认为这部分与我无关紧要)。

感谢您的帮助。 我已经尝试过,但是我的问题是我无法与python保持相同的形状。

3 个答案:

答案 0 :(得分:3)

就像另一个答案一样,我将使用字符串切片来获取最后一列,并使用字符串串联将行重新放回原处。但是,我将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)

答案 1 :(得分:1)

类似于其他答案,但这是另一种选择。进行了字符串反转以将字符串替换为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)

答案 2 :(得分:1)

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

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