Написать скрипт который удаляет из текстового файла пустые строки

Обновлено: 07.07.2024

В вашей "пустой" строке могут быть пробелы или символы табуляции. Используйте классы POSIX с sed чтобы удалить все строки, содержащие только пробелы:

Более короткая версия, которая использует ERE, например, с gnu sed:

(Обратите внимание, что sed НЕ поддерживает PCRE.)

Мне не хватает решения awk :

Что будет возвращено:

Как это работает? Так как NF означает "количество полей", эти пустые строки имеют 0 fiedls, так что awk оценивает от 0 до False и ни одна строка не печатается; однако, если есть хотя бы одно поле, оценка имеет значение True и делает awk выполнение по умолчанию: распечатать текущую строку.

sed '/^$/d' должно быть хорошо, ожидаете ли вы изменить файл? Если это так, вы должны использовать флаг -i .

Я считаю, что это самый простой и быстрый:

Если вам нужно игнорировать все линии белого пространства, попробуйте следующее:

С помощью принятого ответа здесь и принятого ответа выше, я использовал:

Это охватывает все базы и отлично работает для моих нужд. Престижность оригинальным плакатам @Kent и @kev

Вы можете сказать:

Вы можете сделать что-то подобное, используя также "grep":

Это также работает в awk.

Скорее всего, вы видите непредвиденное поведение, потому что ваш текстовый файл был создан в Windows, поэтому в конце последовательности строк \r\n . Вы можете использовать dos2unix для преобразования его в текстовый файл в стиле UNIX перед запуском sed или использованием

удалить пустые строки независимо от того, есть ли возврат каретки.

Мой bash -specific ответ - рекомендую использовать для этого оператор подстановки perl с глобальным флагом g шаблона:

Этот ответ иллюстрирует учет наличия или отсутствия пустых строк в них ( [\ ]* ), а также использование | разделить несколько поисковых терминов/полей. Протестировано на macOS High Sierra и CentOS 6/7.

К сведению, оригинальный sed '/^$/d' $file OP с исходным кодом sed '/^$/d' $file прекрасно работает в терминале bash на macOS High Sierra и CentOS 6/7 Linux на высокопроизводительном суперкомпьютерном кластере.

Это статья про SED.

Вам могут пригодится также статьи AWK и GREP

Примеры я показываю в Bash под Windows 10 или в Bash в Linux .

Основные команды Sed

Для того чтобы применить SED достаточно ввести в командную строку

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

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

Сравните две идентичные команды

Удалить что-то из файла

За удаление отвечает опция d про неё вы можете прочитать отдельную статью sed d

Также можно удалять заменой на пустое место

И удалять с помощью других опций, например, q

Сделать замену

За замену отвечает опция s про неё вы можете прочитать отдельную статью sed s - substitute

Экранирование символов в sed

Пример экранирования точек и кавычек для смены локали в CentOS можете изучить здесь

Предположим, что есть файл input.txt следующего содержания

В результате получим ошибку

Here is a String Here is an Integer Here is a Float

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

Два условия одновременно в Sed

Предположим, что у нас есть файл input.txt следующего содержания

Таким образом, в каждой строчке должно остаться только слово it.

Получить диапазон строк

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

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

Например, Вам нужны строки с 9570 по 9721

Заменить всё между определёнными символами

Удалить всё что находится между квадратными скобками включая скобки

Создать функцию

Чтобы каждый раз не вспоминать команды sed можно создать функцию

Возьмём команду, которая удаляет комментарии и пустые строки из предыдущего примера и запишем как функцию clean_file.

Первым делом в коносли нужно написать в терминале function clean_file < и нажать Enter

$1 означает, что функция будет принимать один аргумент. Это, конечно, будет название файла.

Затем нужно снова нажать Enter и в новой строке написать > и нажать Enter ещё раз

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

clean_file websites
cat websites

Отбросить всё, что левее определённого слова

Предположим, что у нас есть файл input.txt следующего содержания

Here is a String it has a Name Here is an Integer it has a Name Here is a Float it has a Name

Мы хотим отбросить всё, что находится левее слова it, включая слово it, и записать в файл.

Для доступности объясню синтаксис сравнив две команды. Посмотрите внимательно, когда мы заменяем слово Here на There.

There находится между двумя слэшами. Раскрашу их для наглядности в зелёный и красный.

А когда мы хотим удалить что-то, мы сначала описываем, что мы хотим удалить. Например, всё от начала строки до слова it.

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

Отбросить всё, что правее определённого слова

Предположим, что у нас есть файл input.txt следующего содержания

Мы хотим отбросить всё, что находится правее слова is, включая слово is, и записать в файл.

у вас может быть пробел/вкладки в вашей "пустой" строке. Если да, то это поможет:

использует \s для соответствия любому символу пробела.

sed '/^$/d' должно быть хорошо, вы ожидаете, чтобы изменить файл на месте? Если это так, вы должны использовать -i флаг.

возможно, эти строки не пусты, поэтому, если это так, посмотрите на этот вопрос удалите пустые строки из txtfiles, удалите пробелы из начала и конца строки Я считаю, что это то, чего вы пытаетесь достичь.

и awk устранение:

как это работает? С NF означает "количество полей", эти пустые строки имеют 0 fiedls, так что awk оценивает 0 в False и строка не печатается; однако, если есть хотя бы одно поле, оценка истинна и делает awk выполнит действие по умолчанию: печать текущей строки.

Я считаю, что это самый простой и быстрый:

Если вам нужно игнорировать все линии пробела, а затем попробуйте это:

С помощью принятого ответа здесь и принятый ответ выше, я использовал:

Это покрывает все основания и отлично работает для моих нужд. Престижность оригинальных постеров @Kent и @kev

вы можете сказать:

вы можете сделать что-то подобное, используя "grep", тоже:

это работает и в awk.

вы, скорее всего, видите неожиданное поведение, потому что ваш текстовый файл был создан в Windows, поэтому конец последовательности строк \r\n . Вы можете использовать dos2unix для преобразования его в текстовый файл стиля UNIX перед запуском sed или использовать

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

мой bash - конкретный ответ-рекомендовать использовать perl оператор подстановки с глобальным шаблоном g флаг для этого, как показано ниже:

этот ответ иллюстрирует учет того, имеют ли пустые строки пробелы в них ( [\ ]* ), а также используя | для разделения нескольких поисковых терминов / полей. Протестировано на macOS High Sierra и CentOS 6/7.

FYI, исходный код OP sed '/^$/d' $file работает в bash терминал на macOS High Sierra и CentOS 6/7 Linux в высокопроизводительном суперкомпьютерном кластере.

для меня с FreeBSD 10.1 с sed работало только это решение:

Имеется текстовый файл temp6.txt в котором следующая информация:

введите сюда описание изображения

Удаление повторений и пустых строк таким образом

Не работает:

7 и 8 строка (см. рисунок) должны удалиться, как я понимаю, но они остаются. То есть, толку от array_unique и array_filter никакого. Точнее, я скорей всего неправильно использую функции.

Благодаря варианту Алексея Шиманского:

удалось избавиться от пустых строк. Но вот строки повторяются! array_unique бесполезная вещь какая-то. =(

Сопутствующий вопрос. А как отсортировать строки в порядке убывания первых 10 символов (чисел, например: 0000000504, 0000000503 и т.д.)? Я думаю, что лучше всю строку не рассматривать, т.к. там числа с текстом вперемешку. Но не пойму, как задать выборку, которая как бы и будет являться флагом.

ВСЕМ СПАСИБО! ВСЁ СДЕЛАЛА


7 и 8 строка (см. рисунок) должны удалиться, как я понимаю, но они остаются. То есть, толку от array_unique и array_filter никакого. Точнее, я скорей всего неправильно использую функции. trim , использованный как callback в array_filter , запись не уберет. @cyadvert простите, а return strlen($el) > 0; не прокатит?

Удаление повторов у вас прекрасно работает. А с последней строчкой «проблема» не в ней, а в символе новой строки в конце предпоследней строки – собственно, каждая строка с данными заканчивается символом новой строки.

скрин

Чтобы «пустой строки» не было, надо у последней строки с данным отрезать символ новой строки в конце.

Наиболее близко к исходному коду был бы такой вариант:

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

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

В третьей записываем в файл результат – соединяем элементы массива символом новой строки. Так после последней строки этого символа не будет.

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