Страницы

Поиск по вопросам

суббота, 21 декабря 2019 г.

Каким образом удалить строчки выборочно?

#python


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

Вот пример

ATOM 14
ATOM 15
ANISOU 15
ATOM 16
ANISOU 16


нужно удалить все, что начинается с ANISOU
    


Ответы

Ответ 1



Как удалить каждую вторую строку из файла на python? Используя fileinput, чтобы прозрачно создать временный файл, чтобы по месту изменения выполнить: #!/usr/bin/env python3 import fileinput import os with fileinput.FileInput(filename, inplace=True, backup='.bak') as file: for i, line in enumerate(file, start=1): if i & 1: # odd print(line, end='') # keep line (stdout is redirected to the file) os.unlink(filename + '.bak') # remove the backup on success Этот for-цикл можно также записать, используя itertools.islice: import sys from itertools import islice sys.stdout.writelines(islice(file, 0, None, 2)) # keep lines[::2] Если реализация .writelines() не пишет строки по мере поступления, а загружает их всех в память, то можно использовать явный for-цикл, чтобы по одной строке писать, не загружая весь файл в память. Для небольшого файла полный код может использовать .readlines(), чтобы получить список строк (загрузить файл в память) и целиком перезаписать этот файл, рискуя потерять данные если ошибка возникнет: with open(filename) as file: lines = file.readlines()[::2] # lines to keep with open(filename, 'w') as file: file.writelines(lines) Для небольшого файла, заданного с командной строки или стандартного ввода (stdin), пренебрегая возможными ошибками, можно кратко записать: #!/usr/bin/env python3 import fileinput from itertools import islice print("".join(islice(fileinput.input(), 0, None, 2)), end='') это полный скрипт. Использование: $ every-other-line file1 file2 >output_file В более общем случае, чтобы удалить строки по месту из файла, не создавая временный файл и не загружая всё содержимое в память, seek()/tell() работают, но вероятно менее эффективное решение создают: from itertools import islice with open(filename, 'r+') as file: write_offset = file.tell() # where to write next for line in islice(iter(file.readline, ''), 0, None, 2): # keep lines[::2] read_offset = file.tell() # where to read next file.seek(write_offset) file.write(line) write_offset = file.tell() file.seek(read_offset) file.truncate(write_offset) Этот более сложный вариант работает и для файлов, которые как в оперативную память не помещаются так и для которых нет места, чтобы копию на диске создать. нужно удалить все, что начинается с ANISOU Можно адаптировать приведённые выше примеры кода: import fileinput import os with fileinput.FileInput(filename, inplace=True, backup='.bak') as file: for line in file: if not line.startswith('ANISOU'): print(line, end='') # keep line (stdout is redirected to the file) os.unlink(filename + '.bak') # remove the backup on success Можно самостоятельно временный файл создать (к примеру, если в текущей директории не достаточно места для копии файла, можно явно другую директорию указать (на другом диске) и использовать shutil.move(), если необходимо): #!/usr/bin/env python3 from pathlib import Path from tempfile import NamedTemporaryFile path = Path(filename) with path.open() as file, \ NamedTemporaryFile('w', dir=str(path.parent), delete=False) as output_file: for line in file: if not line.startswith('ANISOU'): print(line, end='', file=output_file) Path(output_file.name).replace(path) Загрузив строки в память: with open(filename) as file: lines = [line for line in file if not line.startswith('ANISOU')] with open(filename, 'w') as file: file.writelines(lines) Легко адаптировать к другим условиям, определив keep_line() предикат, к примеру: with open(filename) as file: lines = list(filter(keep_line, file)) with open(filename, 'w') as file: file.writelines(lines) где в данном случае: def keep_line(line): return not line.startswith('ANISOU')

Ответ 2



#!/usr/bin/env python3 #-*- coding: utf-8 -*- f=open("./файл.txt","r") # открытие фала на чтение f2=open("./файл2.txt","w") # открытие файла на запись результата stroka=" " # Создаем не пустую строку, будет использоваться для построчного чтения файла while stroka!="" : # Запускам цикл в котором будет построчно считываться файл, в конце файла параметр stroka станет равен пустой строке и цикл завершится stroka=f.readline() # Построчное чтение файла if stroka[:6]!="ANISOU": f2.write(stroka) # Если строка не начинается с ANISOU то строка запишется в файл результата f.close # закрытие файла f2.close # закрытие файла

Комментариев нет:

Отправить комментарий