Linux удалить последнюю строку файла

Удаление строк из файла с использованием sed

В Unix команда SED удаляет одну или несколько строк из указанного файла по желанию пользователя. Эта утилита используется для работы с командной строкой Unix, для удаления из файла выражений, которые могут быть идентифицированы с помощью определяющего разделителя (например, запятая, табуляция или пробел), по номеру строки или путем поиска строки, выражения или адреса строки в синтаксисе sed.

Sed: удалить одну или несколько строк из файла

Вот как можно удалить одну или несколько строк из файла.

Синтаксис

n = номер строки

string = ряд символов, найденный в строке

regex = регулярное выражение, соответствующее искомому шаблону

addr = адрес строки (номер или шаблон)

d = удалить (delete)

Примеры Sed

Вот несколько примеров использования приведенного выше синтаксиса.

Используйте следующий код, чтобы удалить третью строку:

Удалите строку, содержащую ряд букв «awk», используя:

Вы можете удалить последнюю строку, введя:

Или удалить все пустые строки:

Удалить строку, соответствующую регулярным выражениям (путем исключения одного из них, содержащего цифровые символы, как минимум 1 цифру, расположенные в конце строки):

Удалить интервал между строками 7 и 9:

Та же операция, что и приведенная выше, но с заменой адреса параметрами:

Вышеприведенные примеры отображают изменения только при открытии файла (stdout1 = screen).

Для постоянных изменений в старых версиях (ниже 4) используйте временный файл для GNU sed с использованием команды -i [suffix]:

Источник

Удалить последнюю строку из файла в Bash

У меня есть файл foo.txt , содержащий следующие строки:

Я хочу простую команду, которая приводит к содержанию foo.txt бытия:

-i Вариант не существует в GNU sed версиях старше 3.95, так что вы должны использовать его в качестве фильтра с временным файлом:

Конечно, в этом случае вы также можете использовать head -n -1 вместо sed .

MacOS:

В Mac OS X (по состоянию на 10.7.4) эквивалент sed -i команды выше

На сегодняшний день это самое быстрое и простое решение, особенно для больших файлов:

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

что означает выходные строки, начинающиеся со строки 2.

Не используйте sed для удаления строк сверху или снизу файла — это очень очень медленно, если файл большой.

У меня были проблемы со всеми ответами здесь, потому что я работал с огромным файлом (

300 Гб), и ни одно из решений не масштабировалось. Вот мое решение:

Другими словами: определите длину файла, который вы хотите получить (длина файла минус длина его последней строки, используя bc ), и установите эту позицию как конец файла (используя dd один байт /dev/null на Это).

Это быстро, потому что tail начинает чтение с конца и dd перезаписывает файл на месте, а не копирует (и анализирует) каждую строку файла, что и делают другие решения.

ПРИМЕЧАНИЕ: это удаляет строку из файла на месте! Сделайте резервную копию или протестируйте фиктивный файл перед тем, как опробовать его на своем собственном файле!

Источник

Удалите последнюю строку из файла в Bash

У меня есть файл foo.txt , содержащий следующие строки:

Мне нужна простая команда, которая приводит к тому, что содержимое foo.txt будет:

ОТВЕТЫ

Ответ 1

Опция -i не существует в версиях GNU sed старше 3.95, поэтому вы должны использовать ее как фильтр с временным файлом:

Конечно, в этом случае вы также можете использовать head -n -1 вместо sed .

MacOS:

В Mac OS X (по состоянию на 10.7.4) эквивалентом команды sed -i выше является

Ответ 2

Это, безусловно, самое быстрое и простое решение, особенно в больших файлах:

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

что означает выходные линии, начинающиеся со строки 2.

Не используйте sed для удаления строк из верхней или нижней части файла — это очень медленно, если файл большой.

Ответ 3

У меня были проблемы со всеми ответами здесь, потому что я работал с огромным файлом (

300 Гбит), и ни одно из решений не масштабировалось. Здесь мое решение:

В словах: найдите длину файла, в который вы хотите закончить (длина файла минус длина его последней строки, используя bc ), и установите эту позицию как конец файла ( на dd на один байт /dev/null на него).

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

Читайте также:  Системное администрирование серверов linux

ПРИМЕЧАНИЕ. Это удаляет строку из файла на месте! Сделайте резервную копию или проверку на фиктивный файл перед тем, как попробовать его в своем собственном файле!

Ответ 4

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

Чтобы удалить последнюю строку и также напечатать ее на stdout ( «pop» ), вы можете объединить эту команду с tee :

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

Если вы собираетесь использовать их повторно и хотите обработать ошибки и некоторые другие функции, вы можете использовать команду poptail здесь: https://github.com/donm/evenmoreutils

Ответ 5

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

sed -e ‘$ d’ foo.txt

если вы хотите удалить последнюю строку самого входного файла do

sed -i » -e ‘$ d’ foo.txt

Ответ 6

Для пользователей Mac:

На Mac, head -n-1 не работает. И я пытался найти простое решение (не беспокоясь о времени обработки), чтобы решить эту проблему только с помощью команд «head» и/или «tail».

Я попробовал следующую последовательность команд и был счастлив, что могу решить ее, просто используя команду «tail» [с параметрами, доступными на Mac]. Итак, если вы находитесь на Mac и хотите использовать только «хвост» для решения этой проблемы, вы можете использовать эту команду:

cat file.txt | tail -r | хвост -n +2 | tail -r

Объяснение:

1 > tail -r: просто меняет порядок строк на входе

2 > tail -n +2: это печатает все строки, начиная со второй строки на входе

Ответ 7

Ответ 8

По существу, этот код говорит следующее:

Для каждой строки после первой печати буферизованная строка

для каждой строки, reset буфер

Буфер отстает на одну строку, поэтому вы заканчиваете печать строк 1 до n-1

Ответ 9

Этот фрагмент делает трюк.

Ответ 10

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

Ответ 11

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

Этот знак + означает, что при открытии файла в текстовом редакторе vim курсор будет расположен на последней строке файла.

Теперь просто дважды нажмите d на клавиатуре. Это будет делать именно то, что вы хотите — удалить последнюю строку. После этого нажмите : , затем x , а затем нажмите Enter . Это сохранит изменения и вернет вас в оболочку. Теперь последняя строка была успешно удалена.

Источник

Bash-скрипты, часть 7: sed и обработка текстов

В прошлый раз мы говорили о функциях в bash-скриптах, в частности, о том, как вызывать их из командной строки. Наша сегодняшняя тема — весьма полезный инструмент для обработки строковых данных — утилита Linux, которая называется sed. Её часто используют для работы с текстами, имеющими вид лог-файлов, конфигурационных и других файлов.

Если вы, в bash-скриптах, каким-то образом обрабатываете данные, вам не помешает знакомство с инструментами sed и gawk. Тут мы сосредоточимся на sed и на работе с текстами, так как это — очень важный шаг в нашем путешествии по бескрайним просторам разработки bash-скриптов.

Сейчас мы разберём основы работы с sed, а так же рассмотрим более трёх десятков примеров использования этого инструмента.

Основы работы с sed

Утилиту sed называют потоковым текстовым редактором. В интерактивных текстовых редакторах, наподобие nano, с текстами работают, используя клавиатуру, редактируя файлы, добавляя, удаляя или изменяя тексты. Sed позволяет редактировать потоки данных, основываясь на заданных разработчиком наборах правил. Вот как выглядит схема вызова этой команды:

По умолчанию sed применяет указанные при вызове правила, выраженные в виде набора команд, к STDIN . Это позволяет передавать данные непосредственно sed.

Вот что получится при выполнении этой команды.

Простой пример вызова sed

В данном случае sed заменяет слово «test» в строке, переданной для обработки, словами «another test». Для оформления правила обработки текста, заключённого в кавычки, используются прямые слэши. В нашем случае применена команда вида s/pattern1/pattern2/ . Буква «s» — это сокращение слова «substitute», то есть — перед нами команда замены. Sed, выполняя эту команду, просмотрит переданный текст и заменит найденные в нём фрагменты (о том — какие именно, поговорим ниже), соответствующие pattern1 , на pattern2 .

Выше приведён примитивный пример использования sed, нужный для того, чтобы ввести вас в курс дела. На самом деле, sed можно применять в гораздо более сложных сценариях обработки текстов, например — для работы с файлами.

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

Текстовый файл и результаты его обработки

Здесь применён тот же подход, который мы использовали выше, но теперь sed обрабатывает текст, хранящийся в файле. При этом, если файл достаточно велик, можно заметить, что sed обрабатывает данные порциями и выводит то, что обработано, на экран, не дожидаясь обработки всего файла.

Читайте также:  Конвейер команд linux это

Sed не меняет данные в обрабатываемом файле. Редактор читает файл, обрабатывает прочитанное, и отправляет то, что получилось, в STDOUT . Для того, чтобы убедиться в том, что исходный файл не изменился, достаточно, после того, как он был передан sed, открыть его. При необходимости вывод sed можно перенаправить в файл, возможно — перезаписать старый файл. Если вы знакомы с одним из предыдущих материалов этой серии, где речь идёт о перенаправлении потоков ввода и вывода, вы вполне сможете это сделать.

Выполнение наборов команд при вызове sed

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

Использование ключа -e при вызове sed

К каждой строке текста из файла применяются обе команды. Их нужно разделить точкой с запятой, при этом между окончанием команды и точкой с запятой не должно быть пробела.
Для ввода нескольких шаблонов обработки текста при вызове sed, можно, после ввода первой одиночной кавычки, нажать Enter, после чего вводить каждое правило с новой строки, не забыв о закрывающей кавычке:

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

Другой способ работы с sed

Чтение команд из файла

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

Вот содержимое файла mycommands :

Вызовем sed, передав редактору файл с командами и файл для обработки:

Результат при вызове такой команды аналогичен тому, который получался в предыдущих примерах.

Использование файла с командами при вызове sed

Флаги команды замены

Внимательно посмотрите на следующий пример.

Вот что содержится в файле, и что будет получено после его обработки sed.

Исходный файл и результаты его обработки

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

Схема записи команды замены при использовании флагов выглядит так:

Выполнение этой команды можно модифицировать несколькими способами.

  • При передаче номера учитывается порядковый номер вхождения шаблона в строку, заменено будет именно это вхождение.
  • Флаг g указывает на то, что нужно обработать все вхождения шаблона, имеющиеся в строке.
  • Флаг p указывает на то, что нужно вывести содержимое исходной строки.
  • Флаг вида w file указывает команде на то, что нужно записать результаты обработки текста в файл.

Рассмотрим использование первого варианта команды замены, с указанием позиции заменяемого вхождения искомого фрагмента:

Вызов команды замены с указанием позиции заменяемого фрагмента

Тут мы указали, в качестве флага замены, число 2. Это привело к тому, что было заменено лишь второе вхождение искомого шаблона в каждой строке. Теперь опробуем флаг глобальной замены — g :

Как видно из результатов вывода, такая команда заменила все вхождения шаблона в тексте.

Флаг команды замены p позволяет выводить строки, в которых найдены совпадения, при этом ключ -n , указанный при вызове sed, подавляет обычный вывод:

Как результат, при запуске sed в такой конфигурации на экран выводятся лишь строки (в нашем случае — одна строка), в которых найден заданный фрагмент текста.

Использование флага команды замены p

Воспользуемся флагом w , который позволяет сохранить результаты обработки текста в файл:

Сохранение результатов обработки текста в файл

Хорошо видно, что в ходе работы команды данные выводятся в STDOUT, при этом обработанные строки записываются в файл, имя которого указано после w .

Символы-разделители

Представьте, что нужно заменить /bin/bash на /bin/csh в файле /etc/passwd . Задача не такая уж и сложная:

Однако, выглядит всё это не очень-то хорошо. Всё дело в том, что так как прямые слэши используются в роли символов-разделителей, такие же символы в передаваемых sed строках приходится экранировать. В результате страдает читаемость команды.

К счастью, sed позволяет нам самостоятельно задавать символы-разделители для использования их в команде замены. Разделителем считается первый символ, который будет встречен после s :

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

Выбор фрагментов текста для обработки

До сих пор мы вызывали sed для обработки всего переданного редактору потока данных. В некоторых случаях с помощью sed надо обработать лишь какую-то часть текста — некую конкретную строку или группу строк. Для достижения такой цели можно воспользоваться двумя подходами:

  • Задать ограничение на номера обрабатываемых строк.
  • Указать фильтр, соответствующие которому строки нужно обработать.

Рассмотрим первый подход. Тут допустимо два варианта. Первый, рассмотренный ниже, предусматривает указание номера одной строки, которую нужно обработать:

Обработка только одной строки, номер который задан при вызове sed

Второй вариант — диапазон строк:

Обработка диапазона строк

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

Читайте также:  Ограничения сервер 1с linux

Обработка файла начиная со второй строки и до конца

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

По аналогии с тем, что было рассмотрено выше, шаблон передаётся перед именем команды s .

Обработка строк, соответствующих фильтру

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

Удаление строк

Утилита sed годится не только для замены одних последовательностей символов в строках на другие. С её помощью, а именно, используя команду d , можно удалять строки из текстового потока.

Вызов команды выглядит так:

Мы хотим, чтобы из текста была удалена третья строка. Обратите внимание на то, что речь не идёт о файле. Файл останется неизменным, удаление отразится лишь на выводе, который сформирует sed.

Удаление третьей строки

Если при вызове команды d не указать номер удаляемой строки, удалены будут все строки потока.

Вот как применить команду d к диапазону строк:

Удаление диапазона строк

А вот как удалить строки, начиная с заданной — и до конца файла:

Удаление строк до конца файла

Строки можно удалять и по шаблону:

Удаление строк по шаблону

При вызове d можно указывать пару шаблонов — будут удалены строки, в которых встретится шаблон, и те строки, которые находятся между ними:

Удаление диапазона строк с использованием шаблонов

Вставка текста в поток

С помощью sed можно вставлять данные в текстовый поток, используя команды i и a :

  • Команда i добавляет новую строку перед заданной.
  • Команда a добавляет новую строку после заданной.

Рассмотрим пример использования команды i :

Теперь взглянем на команду a :

Как видно, эти команды добавляют текст до или после данных из потока. Что если надо добавить строку где-нибудь посередине?

Тут нам поможет указание номера опорной строки в потоке, или шаблона. Учтите, что адресация строк в виде диапазона тут не подойдёт. Вызовем команду i , указав номер строки, перед которой надо вставить новую строку:

Команда i с указанием номера опорной строки

Проделаем то же самое с командой a :

Команда a с указанием номера опорной строки

Обратите внимание на разницу в работе команд i и a . Первая вставляет новую строку до указанной, вторая — после.

Замена строк

Команда c позволяет изменить содержимое целой строки текста в потоке данных. При её вызове нужно указать номер строки, вместо которой в поток надо добавить новые данные:

Замена строки целиком

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

Замена строк по шаблону

Замена символов

Команда y работает с отдельными символами, заменяя их в соответствии с переданными ей при вызове данными:

Используя эту команду, нужно учесть, что она применяется ко всему текстовому потоку, ограничить её конкретными вхождениями символов нельзя.

Вывод номеров строк

Если вызвать sed, использовав команду = , утилита выведет номера строк в потоке данных:

Вывод номеров строк

Потоковый редактор вывел номера строк перед их содержимым.

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

Вывод номеров строк, соответствующих шаблону

Чтение данных для вставки из файла

Выше мы рассматривали приёмы вставки данных в поток, указывая то, что надо вставить, прямо при вызове sed. В качестве источника данных можно воспользоваться и файлом. Для этого служит команда r , которая позволяет вставлять в поток данные из указанного файла. При её вызове можно указать номер строки, после которой надо вставить содержимое файла, или шаблон.

Вставка в поток содержимого файла

Тут содержимое файла newfile было вставлено после третьей строки файла myfile .

Вот что произойдёт, если применить при вызове команды r шаблон:

Использование шаблона при вызове команды r

Содержимое файла будет вставлено после каждой строки, соответствующей шаблону.

Пример

Представим себе такую задачу. Есть файл, в котором имеется некая последовательность символов, сама по себе бессмысленная, которую надо заменить на данные, взятые из другого файла. А именно, пусть это будет файл newfile , в котором роль указателя места заполнения играет последовательность символов DATA . Данные, которые нужно подставить вместо DATA , хранятся в файле data .

Решить эту задачу можно, воспользовавшись командами r и d потокового редактора sed:

Замена указателя места заполнения на реальные данные

Как видите, вместо заполнителя DATA sed добавил в выходной поток две строки из файла data .

Итоги

Сегодня мы рассмотрели основы работы с потоковым редактором sed. На самом деле, sed — это огромнейшая тема. Его изучение вполне можно сравнить с изучением нового языка программирования, однако, поняв основы, вы сможете освоить sed на любом необходимом вам уровне. В результате ваши возможности по обработке с его помощью текстов будет ограничивать лишь воображение.

На сегодня это всё. В следующий раз поговорим о языке обработки данных awk.

Уважаемые читатели! А вы пользуетесь sed в повседневной работе? Если да — поделитесь пожалуйста опытом.

Источник

Оцените статью