Подтвердить что ты не робот

Вставить строку в середине файла с помощью Python?

Есть ли способ сделать это? Скажем, у меня есть файл, список имен которого выглядит следующим образом:

  • Alfred
  • Билл
  • Donald

Как я мог вставить третье имя "Чарли" в строку x (в этом случае 3) и автоматически отправить всех остальных по одной строке? Я видел другие вопросы, подобные этому, но они не получили полезных ответов. Может ли это быть сделано, предпочтительно с помощью метода или цикла?

4b9b3361

Ответ 1

Это способ сделать трюк.

f = open("path_to_file", "r")
contents = f.readlines()
f.close()

contents.insert(index, value)

f = open("path_to_file", "w")
contents = "".join(contents)
f.write(contents)
f.close()

"index" и "value" - это строка и значение по вашему выбору, строки, начинающиеся с 0.

Ответ 2

Если вы хотите найти файл подстроки и добавить новый текст в следующую строку, один из элегантных способов сделать это:

import fileinput
for line in fileinput.FileInput(file_path,inplace=1):
    if "TEXT_TO_SEARCH" in line:
        line=line.replace(line,line+"NEW_TEXT")
    print line,

Ответ 3

Вы можете просто прочитать данные в списке и вставить новую запись, где хотите.

names = []
with open('names.txt', 'r+') as fd:
    for line in fd:
        names.append(line.split(' ')[-1].strip())

    names.insert(2, "Charlie") # element 2 will be 3. in your list
    fd.seek(0)
    fd.truncate()

    for i in xrange(len(names)):
        fd.write("%d. %s\n" %(i + 1, names[i]))

Ответ 4

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

  • Alfred
  • Билл
  • Charlie
  • Donald

(Вставьте Charlie, затем добавьте 1 ко всем последующим строкам.) Здесь одно из возможных решений:

def insert_line(input_stream, pos, new_name, output_stream):
  inserted = False
  for line in input_stream:
    number, name = parse_line(line)
    if number == pos:
      print >> output_stream, format_line(number, new_name)
      inserted = True
    print >> output_stream, format_line(number if not inserted else (number + 1), name)

def parse_line(line):
  number_str, name = line.strip().split()
  return (get_number(number_str), name)

def get_number(number_str):
  return int(number_str.split('.')[0])

def format_line(number, name):
  return add_dot(number) + ' ' + name

def add_dot(number):
  return str(number) + '.'

input_stream = open('input.txt', 'r')
output_stream = open('output.txt', 'w')

insert_line(input_stream, 3, 'Charlie', output_stream)

input_stream.close()
output_stream.close()

Ответ 5

Существует множество методов, которые я нашел полезными для решения этой проблемы:

with open(file, 'r+') as fd:
    contents = fd.readlines()
    contents.insert(index, new_string)  # new_string should end in a newline
    fd.seek(0)  # readlines consumes the iterator, so we need to start over
    fd.writelines(contents)  # No need to truncate as we are increasing filesize

В нашем конкретном приложении мы хотели добавить его после определенной строки:

with open(file, 'r+') as fd:
    contents = fd.readlines()
    if match_string in contents[-1]:  # Handle last line to prevent IndexError
        contents.append(insert_string)
    else:
        for index, line in enumerate(contents):
            if match_string in line and insert_string not in contents[index + 1]:
                contents.insert(index + 1, insert_string)
                break
    fd.seek(0)
    fd.writelines(contents)

Если вы хотите, чтобы он вставлял строку после каждого экземпляра совпадения, а не только из первого, удалите else: (и правильно unindent) и break.

Обратите внимание также, что and insert_string not in contents[index + 1]: не позволяет добавить несколько копий после match_string, поэтому можно безопасно запускать несколько раз.

Ответ 6

  • Разберите файл в список python, используя file.readlines() или file.read().split('\n')
  • Определите позицию, в которой вы должны вставить новую строку, в соответствии с вашими критериями.
  • Вставьте новый элемент списка, используя list.insert().
  • Запишите результат в файл.

Ответ 7

Простой, но неэффективный способ - прочитать весь контент, изменить его, а затем переписать:

line_index = 3
lines = None
with open('file.txt', 'r') as file_handler:
    lines = file_handler.readlines()

lines.insert(line_index, 'Charlie')

with open('file.txt', 'w') as file_handler:
    file_handler.writelines(lines)

Ответ 8

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

Вы можете оставить буфер невидимых нулевых символов ('\ 0') в месте вставки для последующей перезаписи:

num_names = 1_000_000    # Enough data to make storing in a list unideal
max_len = 20             # The maximum allowed length of the inserted line
line_to_insert = 2       # The third line is at index 2 (0-based indexing)

with open(filename, 'w+') as file:
    for i in range(line_to_insert):
        name = get_name(i)                    # Returns 'Alfred' for i = 0, etc.
        file.write(F'{i + 1}. {name}\n')

    insert_position = file.tell()             # Position to jump back to for insertion
    file.write('\0' * max_len + '\n')         # Buffer will show up as a blank line

    for i in range(line_to_insert, num_names):
        name = get_name(i)
        file.write(F'{i + 2}. {name}\n')      # Line numbering now bumped up by 1.

# Later, once you have the name to insert...
with open(filename, 'r+') as file:            # Must use 'r+' to write to middle of file 
    file.seek(insert_position)                # Move stream to the insertion line
    name = get_bonus_name()                   # This lucky winner jumps up to 3rd place
    new_line = F'{line_to_insert + 1}. {name}'
    file.write(new_line[:max_len])            # Slice so you don't overwrite next line

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

Ответ 9

location_of_line = 0
with open(filename, 'r') as file_you_want_to_read:
     #readlines in file and put in a list
     contents = file_you_want_to_read.readlines()

     #find location of what line you want to insert after
     for index, line in enumerate(contents):
            if line.startswith('whatever you are looking for')
                   location_of_line = index

#now you have a list of every line in that file
context.insert(location_of_line, "whatever you want to append to middle of file")
with open(filename, 'w') as file_to_write_to:
        file_to_write_to.writelines(contents)

Так я и получил все данные, которые хочу вставить в середину файла.

это просто псевдокод, так как мне было трудно понять, что происходит.

по сути, вы читаете файл целиком и добавляете его в список, затем вставляете нужные строки в этот список и затем перезаписываете в тот же файл.

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