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

268

Я пытаюсь удалить пустые строки, используя sed:

sed '/^$/d'

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

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

xxxxxx


yyyyyy


zzzzzz

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

xxxxxx
yyyyyy
zzzzzz

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

Показать ещё 1 комментарий
Теги:
sed

13 ответов

483
Лучший ответ

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

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

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

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

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

  • 2
    @HuStmpHrrr gnu sed вообще не поддерживает PCRE. это ERE с -r
  • 7
    OS X требуется sed -i "" '/^[[:space:]]*$/d' <filename> ,
Показать ещё 1 комментарий
55

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

awk 'NF' file

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

xxxxxx
yyyyyy
zzzzzz

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

  • 1
    Whoah. Даже работает с «свернутой» версией BSD awk (версия 20121220 (FreeBSD). Спасибо :-)
  • 0
    @ BernieReiter, добро пожаловать :) Да, это очень простая идиоматическая вещь, которую позволяют все версии awk.
Показать ещё 2 комментария
52

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

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

  • 0
    да. Я изменяю файл. * .Csv. как поместить -i в команду sed?
  • 2
    sed -i '/^$/d' - это один из способов сделать это.
24

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

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
  • 3
    cat не нужна, grep принимает файлы: grep . file.txt
  • 3
    Да, я знаю, но в первоначальном вопросе не упоминалось, является ли источник файлом или чем-то еще, поэтому решение - это то, что следует после «|», а перед ним просто пример источника. Просто чтобы отличить решение от источника линий.
Показать ещё 1 комментарий
22
  • 1
    Они корректно отображаются в вашем онлайн-инструменте, но [] не следует экранировать в выражении в скобках, поэтому код здесь не является правильным для \[\[:space:\]\] или \[ \t\] - должен быть [[:space:]] и [ \t] .
13

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

$ 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

4

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

sed -n '/ / p' filename    #there is a space between '//'
  • 0
    .. что означает print all lines except the empty one(s) и молчать
2

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

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

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

  • 0
    Привет, что делает флаг -r , и можно ли его объединить с -i чтобы изменить файл напрямую и избежать печати на экране. Кроме того, я думаю, что эта команда также будет работать как sed -r "/^\r$/d"
2

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

awk '!/^$/' file
xxxxxx
yyyyyy
zzzzzz
2

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

egrep -v "^$" file.txt
0

Еще более простой метод с использованием awk.

Ответ: cat filename.txt | awk 'NF' cat filename.txt | awk 'NF'

awk 'NF' - это удалит все пустые/пустые строки.

Дополнительная информация: cat filename.txt | awk 'NF' | awk '{$1=$1;print}' cat filename.txt | awk 'NF' | awk '{$1=$1;print}'

awk '{$1=$1;print}' - это удалит только конечные пробелы (как левые, так и правые)

0

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

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

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

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

-4

Для меня с 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 =============

Ещё вопросы

Сообщество Overcoder
Наверх
Меню