2012-05-08 3 views
26

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

  1. Альфред
  2. Билл
  3. Дональд

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

+0

Я сомневаюсь, что вы не нашли бы решения для этого с некоторыми фундаментальными исследованиями. Вы уверены, что сделали это? –

+2

@AbhranilDas благодаря хорошей формулировке tkbx Я сразу нашел этот ответ! – dmeu

+0

Связанный: [Как написать в середине текстового файла при чтении его содержимого?] (Http://stackoverflow.com/q/16556944/4279) – jfs

ответ

39

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

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

«Индекс» и «значение» является строкой и значением вашего выбора, строки, начиная с 0.

+4

Это, вероятно, немного более чисто, чем мой ответ, но вы можете не открывать и закрывать файл дважды. – jordanm

+4

Не проще ли использовать 'f.writelines (contents)' вместо того, чтобы присоединяться к нему самостоятельно? – zekel

+0

contents.insert (x, y) Мне это нравится, просто –

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

Просто примечание: 'file.read.split ('\ n ') 'должен быть' file.read(). split (' \ n ') ' – Harry

5

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

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

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

  1. Альфред
  2. Билл
  3. Чарли
  4. Дональд

(Вставьте 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() 
11

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

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, 
+4

На python3 'print (line, end = '')' полезно не вставлять дополнительные строки между строками. –

1

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

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, поэтому можно безопасно запускать несколько раз.

Смежные вопросы