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

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

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

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

11 ответов

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

sed -e ‘$ d’ foo.txt

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

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

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

на Mac, head-n -1 не будет работать. И я пытался найти простое решение [ не беспокоясь о времени обработки], чтобы решить эту проблему только с помощью команд" голова "и/или" хвост".

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

файл cat.txt / tail-r / tail-n +2 / tail-r

объяснение :

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

Читайте также:  Das keyboard 4 professional

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

412716 просмотра

15 ответа

5528 Репутация автора

Мне нужно многократно удалить первую строку из огромного текстового файла, используя скрипт bash.

Сейчас я использую sed -i -e "1d" $FILE — но для удаления требуется около минуты.

Есть ли более эффективный способ достичь этого?

Ответы (15)

16 плюса

621641 Репутация автора

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

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

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

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

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

Затем, в спокойное время (полночь?), Он мог бы выполнить специальную обработку файла A, чтобы удалить все обработанные в настоящее время строки и установить смещение в 0.

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

плюса

5528 Репутация автора

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

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

Читайте также:  Convert exe windows 7

(файл1 содержит строки кода sql)

Автор: Brent Размещён: 04.12.2008 03:40

8 плюса

81074 Репутация автора

Как сказал Пакс, вы, скорее всего, не добьетесь этого быстрее. Причина в том, что почти нет файловых систем, которые поддерживают усечение с самого начала файла, так что это будет n операция O ( ), где n размер файла. То, что вы можете сделать намного быстрее, хотя и перезаписывает первую строку с таким же количеством байтов (возможно, с пробелами или комментарием), которые могут работать для вас в зависимости от того, что вы пытаетесь сделать (что это, кстати?).

-1 плюса

19910 Репутация автора

Будет ли использовать хвост на линиях N-1 и направлять его в файл, а затем удалить старый файл и переименовать новый файл в старое имя?

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

831 плюса

242808 Репутация автора

-n x : Просто напечатайте последние x строки. tail -n 5 даст вам последние 5 строк ввода. + Знак рода переворачивает аргумент и сделать tail печать ничего , кроме первых x-1 строк. tail -n +1 будет печатать весь файл, tail -n +2 все, кроме первой строки, и т. д.

GNU tail намного быстрее, чем sed . tail также доступен в BSD, и -n +2 флаг совместим с обоими инструментами. Проверьте FreeBSD или X OS страниц человека больше.

Версия BSD может быть намного медленнее, чем sed . Интересно, как им это удалось? tail должен просто читать файл строки за строкой, в то время sed как довольно сложные операции включают интерпретацию сценария, применение регулярных выражений и тому подобное.

Примечание. У вас может возникнуть соблазн использовать

но это даст вам пустой файл . Причина в том, что перенаправление ( > ) происходит до того, tail как вызывается оболочкой:

  1. Shell обрезает файл $FILE
  2. Shell создает новый процесс для tail
  3. Shell перенаправляет команду завершения tail процесса на $FILE
  4. tail читает из пустой $FILE

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

&& Будет убедиться , что файл не будет перезаписан , когда есть проблема.

3 плюса

Репутация автора

Как насчет использования csplit?

Автор: crydo Размещён: 04.03.2009 04:08

плюса

9 Репутация автора

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

Читайте также:  Hetman partition recovery 4pda

Автор: Tim Размещён: 14.11.2009 01:42

9 плюса

33063 Репутация автора

Вы можете редактировать файлы на месте: просто используйте -i флаг Perl , например:

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

Автор: alexis Размещён: 15.02.2013 09:40

65 плюса

1001 Репутация автора

Для тех, кто находится на SunOS, который не является GNU, следующий код поможет:

103 плюса

1730 Репутация автора

Вы можете использовать -i для обновления файла без использования оператора «>». Следующая команда удалит первую строку из файла и сохранит ее в файле.

Автор: amit Размещён: 24.11.2014 07:10

5 плюса

4659 Репутация автора

sponge Util позволяет избежать необходимости жонглировать временный файл:

Автор: agc Размещён: 05.08.2016 08:14

3 плюса

1512 Репутация автора

должен показывать строки, кроме первой строки:

Автор: serup Размещён: 29.09.2016 07:42

2 плюса

1104 Репутация автора

Можно использовать vim для этого:

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

1 плюс

63777 Репутация автора

Если вы хотите изменить файл в месте, вы всегда можете использовать оригинал ed вместо его s treaming преемника sed :

плюса

31 Репутация автора

Вы можете сделать это легко с помощью

в командной строке или для удаления первой строки файла из файла используйте «интерактивный режим sed:

У меня есть большой файл (около 30 гб), мне нужно из него вырезать все строки, которые содержат, что либо кроме a-zA-Z0-9 и всех спецсимволов (!@#$%^&*() . и т.д.).

2 ответа 2

добавте в группу что пропущенно

-v игнорировать строки содержащие патерн

После небольших изысканий:

UCS characters U+0000 to U+007F (ASCII) are encoded simply as bytes 0x00 to 0x7F (ASCII compatibility). This means that files and strings which contain only 7-bit ASCII characters have the same encoding under both ASCII and UTF-8.

у grep есть функция чтения бинарных файлов как текст. Получается нужно исключить значения от bx00 до bx7F

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

Рабочий вариант на основе ключевой статьи [4]. Просуммировав все выше перечисленное, нужно найти шестнадцатеричные последовательности удовлетворяющие условие [x00-x7D] но вывести все символы за пределами этого промежутка.

Конечно если речь идет о чем то подобном UNICODE/UTF-8/ASCII, а не "сыром" бинарном файле.

Т.к. вопрос не определен до конца, добавил свой критерий: вывести любую строку НЕ содержащую символ со значением от x00 до x7D.

Ссылка на основную публикацию
Adblock detector