Perl удалить строку из файла

Обновлено: 07.07.2024

Я открываю файл в режиме добавления. Мне нужно заменить строки 2,3 и 4 в файле, а позже мне нужно добавить новые данные в конец файла.

я думаю, что это ответ FAQ, который я перепостил в Stackoverflow больше всего. The perlfaq5 и ответ как изменить, удалить или вставить строку в файл, или добавить в начало файла?.

забудьте о режиме добавления материала. Это только усложнит твою жизнь.

основная идея вставки, изменения или удаления строки из текстового файла включает в себя чтение и печать файла в укажите, что вы хотите внести изменения, внести изменения, а затем прочитать и распечатать остальную часть файла. Perl не обеспечивает произвольный доступ к строкам (особенно с разделителем ввода записи, $/ , является изменяемым), хотя такие модули, как Tie:: File фейк это.

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

в этой основной форме добавьте детали, которые вам нужны вставка, изменение или удаление строк.

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

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

изменить только a конкретная линия,номер входной строки, $. , это полезно. Сначала прочитайте и распечатайте строки до той, которую вы хотите изменить. Затем прочитайте одну строку, которую вы хотите изменить, измените ее и распечатайте. После этого прочитайте остальные строки и распечатайте их:

чтобы пропустить строки, используйте элементы управления циклами. Следующий в этом примере пропускает строки комментариев, а последний останавливает всю обработку, как только он встречает либо __END__ или __DATA__ .

сделайте то же самое, чтобы удалить определенную строку, используя next, чтобы пропустить строки, которые вы не хотите показывать в выходных данных. Этот пример пропускает каждую пятую строку:

если по какой-то странной причине вы действительно хотите увидеть весь файл сразу, а не обрабатывать строку за строкой, вы можете хлебнуть его (до тех пор, пока вы можете поместить все это в память!):

модули, такие как File:: Slurp и Tie:: File может помочь и с этим. Если вы можете, однако, избежать чтения всего файла сразу. Perl не вернет эту память операционной системе до завершения процесса.

вы также можете использовать Perl one-liners для изменения файла на месте. Следующие изменения все 'Фред' to 'Barney' на inFile.txt, перезапись файла с новым содержимым. С -p переключатель, Perl оборачивает петлю времени вокруг код, который вы указываете с помощью -e и -i включает редактирование на месте. Текущая строка находится в $_ . С -p , Perl автоматически печатает значение $_ в конце цикла. См.perlrun для получения более подробной информации.

чтобы сделать резервную копию inFile.txt, дай -i расширение файла, чтобы добавить:

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

чтобы добавить строки перед определенной строкой, вы можете добавить строку (или строки!) до Perl выводит $_ :

вы даже можете добавить строку в начало файла, так как текущая строка печатается в конце цикла:

чтобы вставить строку после одной уже в файле, используйте -n переключатель. Это так же, как -p за исключением того, что он не печатает $_ в конце цикла, так что у вас есть сделать это самому. В этом случае print $_ сначала распечатайте строку, которую вы хотите добавить.

У меня есть огромный текстовый файл, и первые пять его строк выглядят так:

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

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

Я не хочу читать весь файл в массиве и не хочу использовать Tie :: File. Можно ли выполнить мои требования с помощью функции seek and tell? Решение будет очень полезным.

3 ответа

Файл - это последовательность байтов. Мы можем заменить (перезаписать) некоторые из них, но как их удалить ? После того, как файл записан, его байты нельзя «вытащить» из последовательности или каким-либо образом «очистить». (Те, что в конце файла, могут быть отклонены, усекая файл по мере необходимости.)

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

В качестве очень простого примера

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

Поскольку мы действительно используем временный файл, я бы рекомендовал основной модуль File :: Temp для этого.

Это можно сделать более эффективным, но гораздо более сложным, открыв в режиме обновления '+<' , чтобы перезаписать только часть файла. Вы выполняете итерацию до строки с шаблоном, записываете ( tell ) ее положение и длину строки, затем копируете все оставшиеся строки в памяти. Затем seek обратно в позицию минус длина этой строки и выгрузите скопированный остаток файла, перезаписав строку и все, что следует за ней.

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

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

Как только новый файл будет записан, откройте его для чтения и откройте оригинал для записи. Это затирает исходный файл. Затем выполните чтение из нового файла и запись в исходный, копируя таким образом содержимое обратно в тот же индексный дескриптор. Когда закончите, удалите новый файл.

Для начала откройте исходный файл в режиме чтения-записи ( '+<' ). Как только новый файл будет записан, seek в начало оригинала (или в то место, откуда нужно перезаписать) и записать в него содержимое нового файла. Не забудьте также установить конец файла, если новый файл короче,

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

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

У меня есть огромный текстовый файл, и первые пять строк его читаются, как показано ниже:

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

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

Я не хочу читать весь файл в массив, и при этом я не хочу использовать Tie :: File. Можно ли выполнить мое требование с помощью поиска и скажите? Решение будет очень полезно.

3 ответа

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

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

В качестве очень простого примера

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

Поскольку мы действительно используем временный файл, я бы порекомендовал основной модуль File :: Temp для этого.

Это можно сделать более эффективным, но гораздо более сложным, открыв режим обновления '+<' , чтобы перезаписать только часть файл. Вы выполняете итерацию до строки с шаблоном, записываете ( tell ) ее позицию и длину строки, а затем копируете все оставшиеся строки в памяти. Затем seek вернитесь в позицию минус длина этой строки и выведите скопированный остаток файла, перезаписав строку и все, что за ней следует ,

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

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

Как только новый файл записан, откройте его для чтения и откройте оригинал для записи. Это забивает оригинальный файл. Затем прочитайте из нового файла и запишите в исходный, таким образом скопировав содержимое обратно в тот же индекс. Удалите новый файл, когда закончите.

Откройте исходный файл в режиме чтения-записи ( '+<' ) для начала. Как только новый файл записан, seek в начало оригинала (или в место, откуда нужно перезаписать) и запишите содержание нового файла. Не забудьте также указать конец файла, если новый файл короче,

после копирования. Это требует некоторой осторожности, и первый способ, как правило, безопаснее.

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

люди продолжают задавать этот вопрос, и я продолжаю отвечать на него тем же ответом от perlfaq5. Теперь это то, на что мы можем указать на Stackoverflow.

основная идея вставки, изменения или удаления строки из текстового файла включает в себя чтение и печать файла до точки, в которую вы хотите внести изменения, внесение изменений, а затем чтение и печать остальной части файла. Perl не обеспечивает произвольный доступ к строкам (особенно с разделителем ввода записи, $/ , является изменяемым), хотя такие модули, как Tie:: File фейк это.

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

в этой базовой форме добавьте детали, которые необходимо вставить, изменить или удалить строки.

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

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

чтобы изменить только определенную строку, Номер входной строки, $. , это полезно. Сначала прочитайте и распечатайте строки до той, которую вы хотите изменить. Затем прочитайте одну строку, которую вы хотите изменить, измените ее и распечатайте. После этого прочитайте остальные строки и распечатайте их:

чтобы пропустить строки, используйте управление циклом. The next в этом примере пропускает строки комментариев и last останавливает всю обработку как только он сталкивается либо __END__ или __DATA__ .

сделайте то же самое, чтобы удалить определенную строку с помощью next , чтобы пропустить строки, которые вы не хотите показывать в выходные. Этот пример пропускает каждую пятую строку:

если по какой-то странной причине вы действительно хотите увидеть весь файл сразу, а не обрабатывать строку за строкой, вы может хлебать его (до тех пор, пока вы можете поместить все это в память!):

модули, такие как File:: Slurp и Tie:: File может помочь с этим тоже. Если вы можете, однако, избежать чтения всего файла сразу. Perl не вернет эту память операционной системе до завершения процесса.

вы также можете использовать Perl one-liners для изменения файла на месте. Следующие изменения все "Фред" на "Барни" в inFile.txt , переписывая файл с новым содержимым. С -p переключатель, Perl обертывает while петли вокруг кода, который вы указываете с -e и -i включает редактирование на месте. Текущая строка находится в $_ . С -p , Perl автоматически печатает значение $_ в конце цикла. См.perlrun для более подробной информации.

сделать резервную копию inFile.txt , дать -i расширение файла, чтобы добавить:

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

чтобы добавить строки перед определенной строкой, вы можете добавить строку (или строки!) до Perl выводит $_ :

вы даже можете добавить строку в начало файла, так как текущая строка печатается в конце цикла:

чтобы вставить строку после одной уже в файле, используйте -n переключатель. Это как . -p кроме того, что он не печатает $_ в конце цикла, так что вы должны сделать это сами. В этом случае print $_ во-первых, затем распечатать строку, которую вы хотите добавить.

Читайте также: