Удалите пустые строки с помощью sed

Я пытаюсь удалить пустые строки с помощью sed:

sed '/^$/d'

но мне с этим не везет.

Например, у меня есть такие строки:

xxxxxx


yyyyyy


zzzzzz

и я хочу, чтобы это было так:

xxxxxx
yyyyyy
zzzzzz

Какой для этого должен быть код?


person jonas    schedule 07.05.2013    source источник
comment
ваша команда sed выглядит нормально, она должна работать   -  person perreal    schedule 07.05.2013
comment
Вышеупомянутая команда не будет работать, даже если у вас нет пробела / табуляции, но есть CR + LF окончания строки.   -  person devnull    schedule 07.05.2013
comment


Ответы (15)


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

sed '/^[[:space:]]*$/d'

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

sed -r '/^\s*$/d'

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

person Kent    schedule 07.05.2013
comment
@HuStmpHrrr gnu sed вообще не поддерживает PCRE. это ERE с -r - person Kent; 17.02.2015
comment
OS X требуется sed -i "" '/^[[:space:]]*$/d' <filename>, - person jww; 04.10.2016
comment
@BernieReiter ^\s*$ будет соответствовать всем пустым строкам, пустое здесь означает, что строка не содержит символов или строка содержит только пустые строки (например, пробелы). Все совпавшие строки будут удалены sed командой d. - person Kent; 26.02.2017
comment
Возможно sed '/\S/!d' file - person potong; 30.07.2020

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

awk 'NF' file

Что вернется:

xxxxxx
yyyyyy
zzzzzz

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

person fedorqui 'SO stop harming'    schedule 09.04.2015
comment
Ого. Работает даже с минимизированной версией awk от BSD (версия 20121220 (FreeBSD). Спасибо :-) - person Bernie Reiter; 25.02.2017
comment
@BernieReiter, пожалуйста :) Да, это очень простая идиоматическая вещь, которую допускают все версии awk. - person fedorqui 'SO stop harming'; 26.02.2017
comment
И это намного быстрее, хотя - для быстрого и грязного теста - я вызываю awk дважды: $ time (topic companies <data.tpx | awk 'NF' - | awk -f dialog_menu.awk -) real 0m0.006s user 0m0.000s sys 0m0.008s $ time (topic companies <data.tpx | gsed '/^\s*$/d' | awk -f dialog_menu.awk -) real 0m0.014s user 0m0.002s sys 0m0.006s Знаете ли вы отличный способ включить это в awk-скрипт, например, шаблон ? awk '/ mypattern / {делать что-нибудь ...}' - person Bernie Reiter; 28.02.2017
comment
@BernieReiter, можно сказать awk 'NF {do stuff...}'. - person fedorqui 'SO stop harming'; 28.02.2017
comment
Обратите внимание, что при этом будут игнорироваться только строки с пробелами. - person wisbucky; 26.04.2019

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

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

person Alberto Zaccagni    schedule 07.05.2013
comment
да. я изменяю файл. * .csv. как поместить -i в команду sed? - person jonas; 07.05.2013
comment
sed -i '/^$/d' - один из способов сделать это. - person Alberto Zaccagni; 07.05.2013

sed

grep

awk

person Oleg Mazko    schedule 25.08.2016
comment
Они правильно отображаются в вашем онлайн-инструменте, но [] не следует экранировать в выражении скобок, поэтому код здесь неверен для \[\[:space:\]\] или \[ \t\] - должно быть [[:space:]] и [ \t]. - person Benjamin W.; 10.08.2018
comment
@BenjaminW. Спасибо, что уловили это. Они были не от первоначального автора, а из Edit 3, когда он был изменен с обычного текста на код, который затем подвергся экранирование `\`. Я исправил их сейчас. - person wisbucky; 26.04.2019

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

cat file.txt | grep .

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

cat file.txt | grep '\S'

Пример:

s="\
\
a\
 b\
\
Below is TAB:\
    \
Below is space:\
 \
c\
\
"; echo "$s" | grep . | wc -l; echo "$s" | grep '\S' | wc -l

выходы

7
5
person Vadim    schedule 17.10.2014
comment
cat не требуется, grep также принимает файлы: grep . file.txt - person Ciro Santilli 新疆再教育营六四事件ۍ 16.05.2016
comment
Да, я знаю, но в первоначальном вопросе не упоминалось, является ли источник файлом или чем-то еще, поэтому решение - это то, что идет после |, а перед ним - просто пример источника. Просто отличить раствор от источника строк. - person Vadim; 17.05.2016
comment
grep '\S' определенно не переносится. Если у вас есть grep -P, вы можете использовать grep -P '\S', но он также поддерживается не на всех платформах. - person tripleee; 09.01.2017
comment
Обратной стороной grep . по сравнению с другими решениями является то, что он выделяет весь текст красным цветом. Остальные решения позволяют сохранить оригинальные цвета. Сравните unbuffer apt search foo | grep . с unbuffer apt search foo | grep -v ^$ - person wisbucky; 26.04.2019

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

$ sed 's/^ *//; s/ *$//; /^$/d; /^\s*$/d' file.txt > output.txt

`s/^ *//`  => left trim
`s/ *$//`  => right trim
`/^$/d`    => remove empty line
`/^\s*$/d` => delete lines which may contain white space

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

person ConMan    schedule 25.07.2014

Другой вариант без sed, awk, perl и т. Д.

strings $file > $output

strings - распечатать строки печатаемых символов в файлах.

person user319660    schedule 01.05.2020
comment
Вы имеете в виду strings вместо string? - person Mickael B.; 02.05.2020

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

sed -n '/ / p' filename    #there is a space between '//'
person tank    schedule 27.05.2014
comment
.. что означает print all lines except the empty one(s)и молчи - person Timo; 24.02.2018

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

sed -r "/^\r?$/d"

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

person Douglas Daseeco    schedule 04.03.2017
comment
Привет, что делает флаг -r и можно ли объединить его с -i, чтобы напрямую изменить файл и избежать вывода на экран. Кроме того, я думаю, что эта команда также будет работать как sed -r "/^\r$/d" - person Alexander Cska; 25.11.2018

Вы также можете сделать что-то подобное с помощью "grep":

egrep -v "^$" file.txt
person Lowbit    schedule 11.08.2014

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

awk '!/^$/' file
xxxxxx
yyyyyy
zzzzzz
person Claes Wikner    schedule 25.08.2016

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

$ perl -pe s'/^\n|^[\ ]*\n//g' $file
xxxxxx
yyyyyy
zzzzzz

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

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

person justincbagley    schedule 24.07.2018

Команда, которую вы пытаетесь выполнить, верна, просто используйте с ней флаг -E.

sed -E '/^$/d'

Флаг -E заставляет sed перехватывать расширенные регулярные выражения. Подробнее здесь

person Samuel Kenneth    schedule 08.05.2021
comment
В этом конкретном регулярном выражении нет ничего, что требовало бы флага -E. - person tripleee; 10.05.2021

Использование редактора vim для удаления пустых строк

:%s/^$\n//g

person Nilesh Shukla    schedule 09.04.2021

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

sed -e '/^[     ]*$/d' "testfile"

внутри [] есть символы пробела и табуляции.

тестовый файл содержит:

fffffff next 1 tabline ffffffffffff

ffffffff next 1 Space line ffffffffffff

ffffffff empty 1 lines ffffffffffff

============ EOF =============
person Vitaly    schedule 17.03.2017