Как изменить только один столбец в текстовом файле, оставив все то же самое и с учетом пробелов? - PullRequest
0 голосов
/ 29 июня 2018

У меня есть файл с большим количеством строк. В безопасном месте я просто 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 голосов
/ 29 июня 2018

Аналогично другим ответам, но здесь есть еще один вариант. Строки обращаются, чтобы заменить строку вправо> влево.

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)
0 голосов
/ 29 июня 2018

Я также использовал десятичную математику и нарезку строк. Вот моя версия:

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))
0 голосов
/ 29 июня 2018

Как и другой ответ, я бы использовал нарезку строк, чтобы получить только последний столбец, и конкатенацию строк, чтобы снова соединить строку. Тем не менее, я бы использовал 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)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...