Удалить последнюю строку в файле python
допустим, у меня есть текстовый файл, полный псевдонимов, как я могу удалить конкретный псевдоним из этого файла?
предполагая, что ваш файл имеет формат одного псевдонима на строку, используйте это.
Сначала откройте файл:
далее, Получить все строки из файла:
теперь вы можете закрыть файл:
и снова открыть его в режиме записи:
затем напишите свои строки обратно, кроме строки, которую вы хотите удалить. Возможно, вы захотите изменить "\n" к любой строке, заканчивающейся вашим файлом.
At конец, закройте файл снова.
решение этой проблемы только один:
Это решение открывает файл в режиме r / w ("r+") и использует seek для сброса F-указателя, а затем усекает, чтобы удалить все после последней записи.
лучший и самый быстрый вариант, вместо того, чтобы хранить все в списке и повторно открывать файл для его записи, по-моему, переписать файл в другом месте.
вот именно! В одном цикле, и только вы можете сделать то же самое. Это будет намного быстрее.
это "вилка" от @Lotherответ (который я считаю, что следует считать правильным ответом).
Для такого файла:
эта вилка из решения Lother отлично работает:
- with open , которые отбрасывают использование f.close()
- более яснее if/else для оценки, если строка отсутствует в текущей строке
проблема с чтением строк в первом проходе и внесением изменений (удаление определенных строк) во втором проходе заключается в том, что если размеры файлов огромны, у вас закончится ОЗУ. Вместо этого лучше читать строки одну за другой и записывать их в отдельный файл, исключая те, которые вам не нужны. Я запустил этот подход с файлами размером 12-50 ГБ, и использование ОЗУ остается почти постоянным. Только циклы CPU показывают, что обработка продолжается.
если вы используете Linux, вы можете попробовать следующий подход.
Предположим, у вас есть текстовый файл с именем animal.txt :
удалить первую строку:
Я думаю, если Вы читаете файл в список, то вы можете перебирать список, чтобы найти псевдоним, от которого хотите избавиться. Вы можете сделать это очень эффективно, не создавая дополнительных файлов, но вам придется записать результат обратно в исходный файл.
вот как я мог бы это сделать:
Я предполагаю, что nicknames.csv содержит такие данные, как:
затем загрузите файл в список:
далее, повторите список чтобы соответствовать вашим входам для удаления:
наконец, записать результат обратно в файл:
не очень хорошо решить, если вы поместите весь файл в память, я знаю, что в настоящее время у всех есть тонны памяти, но подумайте, если файл несколько ГБ журналов или что-то еще.
лучший способ скопировать его строка за строкой в новый файл, чем удалить первый или что-то вроде этого
В общем, вы не можете; вы должны написать весь файл снова (по крайней мере, с момента изменения до конца).
в некоторых случаях вы можете сделать лучше, чем это -
Если все ваши элементы данных одинаковой длины и в определенном порядке, и вы знаете смещение того, от которого вы хотите избавиться, вы можете скопировать последний элемент поверх того, который будет удален, и усечь файл перед последним элементом;
или вы можете просто перезаписать фрагмент данных с помощью значения "это плохие данные, пропустите его" или сохраните флаг "этот элемент был удален"в сохраненных элементах данных, чтобы вы могли пометить его удаленным без изменения файла.
Это, вероятно, перебор для коротких документов (что-нибудь под 100 КБ?).
Мне понравился подход fileinput, как описано в этот ответ: удаление строки из текстового файла (python)
скажем, например, у меня есть файл, в котором есть пустые строки, и я хочу удалить пустые строки, Вот как я его решил:
Примечание: пустые строки в моем случае имели длину 1
Наверное, вы уже получили правильный ответ,но вот мой. Вместо того, чтобы использовать список для сбора нефильтрованных данных (что readlines() метод), я использую два файла. Один предназначен для хранения основных данных, а второй-для фильтрации данных при удалении определенной строки. Вот код:
надеюсь, вы найдете это полезным! :)
сохраните строки файла в списке, затем удалите из списка строку, которую вы хотите удалить, и запишите оставшиеся строки в новый файл
возьмите содержимое файла, разделите его по новой строке на кортеж. Затем получите доступ к номеру строки кортежа, присоединитесь к кортежу результата и перезапишите файл.
Как можно удалить самую последнюю строку файла с python?
Пример входного файла:
Пример вывода файла:
Я создал следующий код, чтобы найти количество строк в файле - но я не знаю, как удалить конкретный номер строки. Я новичок в Python - так что, если есть более простой способ - пожалуйста, скажите мне.
РЕДАКТИРОВАТЬ:
Я выяснил это, используя различные ответы: в основном Strawberry's и что-то, что я видел в сети (извините, я не могу найти ссылку).
Вы можете использовать приведенный выше код, а затем:
Это даст вам массив строк, содержащий все строки, кроме последней.
Вот более общее решение с эффективным использованием памяти, позволяющее пропускать последние n строк (например, команда head ):
Вот еще один способ, не хлебая весь файл в память
Хотя я не проверял это (пожалуйста, не ненавижу это), я считаю, что есть более быстрый способ сделать это. Это скорее решение C, но вполне возможно в Python. Это не Pythonic, либо. Это теория, я бы сказал.
Во-первых, вам нужно знать кодировку файла. Задайте для переменной число байтов, которое использует символ в этой кодировке (1 байт в ASCII). CHARsize (почему бы и нет). Вероятно, будет 1 байт с ASCII-файлом.
Затем выберите размер файла и установите для него FILEsize .
Предположим, у вас есть адрес файла (в памяти) в FILEadd .
Добавьте FILEsize в FILEadd .
Переместите обратные слова (увеличение на -1 *** CHARsize **), проверяя каждый байт CHARsize на \ n (или любой символ новой строки, используемый вашей системой). Когда вы дойдете до первой \ n, у вас будет позиция начала первой строки файла. Замените \ n на \ x1a (26, ASCII для EOF или что-то еще в вашей системе / с кодировкой).
Очистите, как вам нужно (измените размер файла, коснитесь файла).
Если это сработает так, как я подозреваю, вы сэкономите много времени, так как вам не нужно читать весь файл с самого начала, вы читаете с конца.
Допустим, у меня есть текстовый файл, полный псевдонимов. Как я могу удалить определенный ник из этого файла, используя Python?
Сначала откройте файл и получите все свои строки из файла. Затем снова откройте файл в режиме записи и запишите свои строки обратно, за исключением строки, которую вы хотите удалить:
Вам нужно strip("\n") символ новой строки в сравнении, потому что если ваш файл не заканчивается символом новой строки, самый последний line тоже не будет.
Возьмите содержимое файла, разбейте его на новую строку в кортеж. Затем получите доступ к номеру строки вашего кортежа, присоедините его к кортежу результата и перезапишите файл.
Возможно, вы уже получили правильный ответ, но здесь мой. Вместо того чтобы использовать список для сбора нефильтрованных данных (что делает метод readlines() ), я использую два файла. Один предназначен для хранения основных данных, а второй - для фильтрации данных при удалении определенной строки. Вот код:
Надеюсь, вы найдете это полезным! :)
В общем, вы не можете; Вы должны написать весь файл снова (по крайней мере, с момента изменения до конца).
В некоторых конкретных случаях вы можете сделать лучше, чем это -
Если все ваши элементы данных имеют одинаковую длину и не в определенном порядке, и вы знаете смещение того, от которого хотите избавиться, вы можете скопировать последний элемент поверх того, который нужно удалить, и обрезать файл до последнего элемента ;
Или вы можете просто перезаписать блок данных значением «это плохие данные, пропустить его» или оставить флаг «этот элемент был удален» в ваших сохраненных элементах данных, чтобы вы могли пометить его как удаленный, не изменяя файл другим способом.
Это, вероятно, излишне для коротких документов (что-нибудь под 100 КБ?).
Вот еще один метод, чтобы удалить / некоторые строки из файла:
Проблема с чтением строк на первом проходе и внесением изменений (удалением определенных строк) на втором проходе заключается в том, что если у вас большие размеры файлов, вам не хватит оперативной памяти. Вместо этого, лучший подход - читать строки по одной и записывать их в отдельный файл, исключая ненужные. Я использовал этот подход для файлов размером 12-50 ГБ, и использование ОЗУ остается практически постоянным. Только циклы процессора показывают обработку в процессе.
Мне нравится этот метод с использованием fileinput и метода «inplace»:
Это немного менее многословно, чем другие ответы и достаточно быстро для
Сохраните строки файла в списке, затем удалите из списка строку, которую хотите удалить, и запишите оставшиеся строки в новый файл.
Это «ответвление» от ответа @Lother (который, я считаю, следует считать правильным ответом).
Для такого файла:
Эта вилка из решения Лотера отлично работает:
- with open , который отказывается от использования f.close()
- более понятный if/else для оценки, если строка не присутствует в текущей строке
Я думаю, что если вы прочитаете файл в список, то выполните итерацию по списку, чтобы найти псевдоним, от которого вы хотите избавиться. Вы можете сделать это очень эффективно, не создавая дополнительные файлы, но вам придется записать результат обратно в исходный файл.
Вот как я могу это сделать:
Я предполагаю, что nicknames.csv содержит такие данные:
Затем загрузите файл в список:
Далее, переходим к списку, чтобы соответствовать вашим входам для удаления:
Наконец, запишите результат обратно в файл:
Решение этой проблемы только с одним открытием:
Это решение открывает файл в режиме r / w («r +») и использует поиск, чтобы сбросить f-указатель, а затем усечь, чтобы удалить все после последней записи.
Если вы используете Linux, вы можете попробовать следующий подход.
Предположим, у вас есть текстовый файл с именем animal.txt :
Удалить первую строку:
Мне понравился подход fileinput, как объяснено в этом ответе: Удаление строки из текстового файла (python)
Например, у меня есть файл с пустыми строками, и я хочу удалить пустые строки, вот как я решил это:
Примечание: пустые строки в моем случае имели длину 1
Вы можете использовать библиотеку re
Предполагая, что вы можете загрузить свой полный текстовый файл. Затем вы определяете список нежелательных псевдонимов, а затем заменяете их пустой строкой "".
Лучший и самый быстрый вариант, вместо того, чтобы хранить все в списке и заново открывать файл, чтобы записать его, - по моему мнению, переписать файл в другом месте.
Это оно! В одном цикле и только один вы можете сделать то же самое. Это будет намного быстрее.
Оператор with отлично подходит для автоматического открытия и закрытия файлов.
+1 за использование «с» и хорошей питонической итерации по строкам, в дополнение к тому, что хорошие выходные строки не мутируются.
Похоже, что это решение будет иметь проблемы с буферизацией/перезаписью для любого файла, превышающего размер входного буфера. И если это не так, может кто-нибудь объяснить, почему?
Это отлично работает для всего, кроме удаления пустых строк, уже существующих между данными в текстовом файле.
Python 3: ValueError: должен иметь ровно один из режимов создания/чтения/записи/добавления. Действительно ли это решение работает?
Форматирование Markdown использует конечные пробелы. Удаление простого изменения этого ответа приведет к разделению строк только пробелами и сохранению конечных пробелов: if line.rstrip(): print line
@Thomas, а почему у поля в файле должно быть окончание «\n»? Если в файле есть "\n", то я бы поспорил, что это литерал. Если это действительно "\n", то следующее поле будет на следующей строке. не так ли? или я все еще пропускаю то, что вы говорите? Если это обязательно, пожалуйста, предоставьте свое объяснение в качестве ответа, так как комментарий трудно прочитать.
@ Ghostdog74 Дело не в разрывах строк, а во вкладках. Если вы обрежете вкладки с конца каждой строки, то каждая строка в таблице будет иметь разное количество столбцов.
Я знаю, что вы спрашивали о Python, но ваш комментарий о Win и Linux указывает на то, что вы стремитесь к кроссплатформенности, а Perl, по крайней мере, так же кроссплатформен, как Python. Вы можете легко сделать это с помощью одной строки Perl в командной строке, никаких скриптов не требуется: perl -ne 'print if /\S/' foo.txt
(Я люблю Python и предпочитаю его Perl в 99% случаев, но иногда мне действительно хочется, чтобы я мог делать с ним сценарии командной строки, как вы можете с помощью переключателя -e на Perl!)
Тем не менее, следующий скрипт Python должен работать. Если вы планируете делать это часто или для больших файлов, его также следует оптимизировать с помощью компиляции регулярных выражений.
Есть много способов сделать это, это только один :)
Вы можете выполнять сценарии командной строки с помощью python, используя -c флаг. К сожалению, вам придется использовать несколько строк (или разделение с помощью ;), чтобы читать со стандартного ввода.
Это зависит от того, что означает «пустой» - это работает, только если пустой означает «вообще ничего». Если между второй строкой и третьей строкой есть пробелы, это не удастся. Плюс он должен работать с файлами :) Но мне нравится, что вам не нужно импортировать регулярные выражения :)
Как можно удалить самую последнюю строку файла с помощью python?
Пример входного файла:
Пример выходного файла:
Я создал следующий код, чтобы найти количество строк в файле, но я не знаю, как удалить конкретный номер строки.
Вы действительно пытаетесь удалить строку из файла на диске? Если это так, убедитесь, что вы понимаете, что файлы не имеют «строк» с точки зрения файловой системы. Линии — это условность программистов и программ. То, что вы видите как «линию», представляет собой последовательность байтов где-то посреди множества других байтов. Чтобы удалить последнюю «строку», вы можете обрезать файл до байта, соответствующего первому символу в строке. Это не сложно (нужно только найти), но в этом нет особого смысла, если задействованные файлы имеют небольшой размер.
Вы уже «удаляете все пустые строки» в Python? То есть вы на самом деле не пытаетесь удалить последнюю строку файла, не так ли? Вы на самом деле читаете файл в память, чтобы удалить пустые строки и выполнить другую обработку? И одна из вещей, которую вы хотите сделать, это удалить последнюю строку перед записью файла обратно? Насколько это близко к тому, чего вы действительно хотите?
? Файл не содержит пустых строк? Приведенный выше пример — это то, на что вы должны обратить внимание, и ничего больше. Последняя строка - это то, что мне нужно удалить. Почему снисходительность? Я почти понял ответ Strawberry.
Поскольку я обычно работаю с многогигабайтными файлами, цикл, как указано в ответах, у меня не сработал. Решение, которое я использую:
Я столкнулся с некоторыми проблемами совместимости (используя Py3) при использовании этого метода для файлов, которые использовались как на Mac, так и на Windows, потому что внутри Mac используется другой разделитель строк, чем Windows (который использует 2: cr и lf). Решение состояло в том, чтобы открыть файл в двоичном режиме чтения ("rb+") и найти двоичный символ новой строки b"\n".
Вы можете использовать приведенный выше код, а затем: -
Это даст вам массив строк, содержащий все строки, кроме последней.
Это может не сработать для файлов размером более мегабайта или двух. Зависит от вашего определения "хорошо". Это должно быть прекрасно для любого настольного использования для нескольких тысяч строк.
Назарий: Невозможно удалить конкретную строку. Однако вы можете обрезать файл или добавить к нему. Поскольку вы хотите удалить последнюю строку, вы можете просто обрезать.
Это не использует python, но python - неправильный инструмент для работы, если это единственная задача, которую вы хотите. Вы можете использовать стандартную утилиту *nix head и запустить
который скопирует все, кроме последней строки имени файла, в новый файл.
Я подозреваю, что версия Python с seek меньшим потреблением оперативной памяти и, следовательно, больше подходит для очень больших файлов, в то время как head это хорошая однострочная версия, но включает чтение и копирование почти полного файла.
Предполагая, что вам нужно сделать это в Python и у вас есть достаточно большой файл, для которого недостаточно нарезки списка, вы можете сделать это за один проход по файлу:
Не самый элегантный код в мире, но он выполняет свою работу.
В основном он буферизует каждую строку в файле через переменную last_line, каждая итерация выводит строку предыдущей итерации.
вот мое решение для пользователей Linux:
нет необходимости читать и перебирать файл в python.
В системах, где работает file.truncate() , вы можете сделать что-то вроде этого:
Согласно моим тестам, file.tell() не работает при чтении построчно, предположительно из-за того, что буферизация сбивает его с толку. Вот почему это суммирует длины линий, чтобы определить позиции. Обратите внимание, что это работает только в системах, где разделитель строк заканчивается на «\n».
Очень опасно на платформе, которая использует более одного символа для "конца строки". как в Windows.
Хорошая точка зрения. (Именно поэтому я изначально собирался использовать tell(), но это не сработало.) В этом случае открытие файла в двоичном режиме должно работать.
Хотя я не проверял это (пожалуйста, не ненавидьте за это), я считаю, что есть более быстрый способ. Это больше похоже на решение C, но вполне возможно на Python. Это тоже не Pythonic. Я бы сказал, это теория.
Во-первых, вам нужно знать кодировку файла. Задайте для переменной количество байтов, которые использует символ в этой кодировке (1 байт в ASCII). CHARsize (почему бы и нет). Вероятно, это будет 1 байт с файлом ASCII.
Затем возьмите размер файла, установите для него FILEsize .
Предположим, у вас есть адрес файла (в памяти) в FILEadd .
Добавьте FILEsize в FILEadd .
Переместите обратные слова (увеличьте на -1 *** CHARsize **), проверяя каждый байт CHARsize на наличие \n (или любого другого символа новой строки, используемого вашей системой). Когда вы дойдете до первого \n, у вас появится позиция начала первой строки файла. Замените \n на \x1a (26, ASCII для EOF или что-то другое в вашей системе/с кодировкой).
Очистите, как вам нужно (измените размер файла, коснитесь файла).
Если это работает так, как я подозреваю, вы сэкономите много времени, так как вам не нужно читать весь файл с начала, вы читаете с конца.
Читайте также: