Как я могу перезаписать строку в файле с помощью python?

Итак, у меня есть текстовый файл (называемый «Числа»), который выглядит так:

1 - 2 - 3 - 8 - 5 - 6  
1 - 2 - 3 - 4 - 5 - 6  
1 - 2 - 3 - 4 - 5 - 6  
1 - 2 - 3 - 4 - 5 - 6  

Я хочу заменить цифру 8 в первой строке на цифру 4. Как мне это сделать?
Пока что у меня получилось следующее:

File = open('Numbers.txt','r+')  
for line in File:
  Row = line.split(' - ')
  FourthValue = Row[3]
  NewFourthValue = '4'
  NewLine = line.replace(FourthValue,NewFourthValue)
  File.write(NewLine)
  break
File.close()

Затем он добавляет новую правильную строку в конец файла следующим образом:

1 - 2 - 3 - 8 - 5 - 6  
1 - 2 - 3 - 4 - 5 - 6  
1 - 2 - 3 - 4 - 5 - 6  
1 - 2 - 3 - 4 - 5 - 61 - 2 - 3 - 4 - 5 - 6

Что я могу сделать, чтобы эта новая строка заменила первую строку?


person MiniMo    schedule 26.06.2016    source источник
comment
Это должно быть очень похоже, stackoverflow.com/questions/39086/   -  person J.J. Hakala    schedule 26.06.2016
comment
Я хочу, чтобы это было намного проще, я всего лишь программист-любитель. @Дж.Дж.Хакала   -  person MiniMo    schedule 26.06.2016
comment
вы просто не можете обрабатывать текстовый файл в режиме чтения/записи. Вы должны прочитать данные, закрыть и снова открыть предыдущий файл в письменной форме и записать новые данные.   -  person Jean-François Fabre    schedule 26.06.2016


Ответы (2)


После прочтения первой строки вам нужно «перемотать» файл, чтобы вы могли перезаписать первую строку.

with open(fname, 'r+') as f:
    row = f.readline()
    row = row.replace('8', '4')
    f.seek(0)
    f.write(row)

Однако будьте осторожны при этом, потому что, если новые данные не будут точно того же размера, что и старые данные, вы испортите следующие строки. Как правило, гораздо проще и безопаснее создать новый файл, скопировав (возможно, измененные) строки из одного файла в другой, но полезно знать этот метод, если вам когда-либо придется обрабатывать большие файлы.

FWIW, мой ответ здесь обрабатывает более общий случай модификации данных на месте в произвольной позиции в файле.

person PM 2Ring    schedule 26.06.2016
comment
Большое спасибо! - person MiniMo; 26.06.2016

Текстовые файлы проблематично переписывать, потому что они часто имеют записи переменной длины, однако у вас фиксированная длина, поэтому:

fh = open('gash.txt','r+') 

# read the first line
line = fh.readline()
row = line.split(' - ')
fourthValue = row[3]

newFourthValue = '4'
newLine = line.replace(fourthValue, newFourthValue)

В этот момент "текущая позиция в файле" находится в начале следующей строки, поэтому мы должны переместить ее обратно в начало текущей записи.

fh.seek(0)
fh.write(newLine)

fh.close()

Это очень упрощенно. Строка вопроса - это первая строка. Если бы это было где-то еще, нам пришлось бы запоминать позицию в файле перед каждой строкой, используя fh.tell(), а затем используя это число в fh.seek().

РЕДАКТИРОВАТЬ: В ответ на вопрос «Если бы я хотел заменить значение в 4-й строке, а не в первой», это заменяет 4 на 8 в четвертой строке.

lineToChange = 4
fieldToChange = 3
newValue = '8'
sep = ' - '
lineno = 0

fh = open('gash.txt','r+')

while True:
    # Get the current file position
    start_pos = fh.tell()

    # read the next line
    line = fh.readline()
    if not line: break          # exit the loop at EOF

    lineno += 1

    if lineno == lineToChange:
        row = line.split(sep)

        # A different replace mechanism
        row[fieldToChange] = newValue
        newLine = sep.join(row)

        # before writing, we must move the file position
        fh.seek(start_pos)
        fh.write(newLine)

fh.close()

Обратите внимание, это работает только потому, что мы заменяем один символ другим. Если бы мы хотели заменить, скажем, 8 на 10, то это не сработало бы, потому что теперь длина строки была бы другой, и мы перезаписали бы начало следующей строки.

person cdarke    schedule 26.06.2016
comment
Большое спасибо. Одна вещь, однако, есть ли способ, которым я могу контролировать положение курсора в файле? Так, например, если я хочу заменить значение в 4-й строке, а не в первой, могу ли я использовать fh.tell или fh.seek, чтобы помочь мне? @cdarke - person MiniMo; 26.06.2016