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

164

Я пытался grep -v '^$'в Linux, и это не сработало. Этот файл пришел из файловой системы Windows.

узел ниндзя
источник

Ответы:

301

Попробуйте следующее:

grep -v -e '^$' foo.txt

-eОпция позволяет шаблоны регулярных выражений для согласования.

Одиночные кавычки ^$заставляют его работать на Cshell. Другие оболочки будут счастливы с одинарными или двойными кавычками.

ОБНОВЛЕНИЕ: Это работает для меня с файлом с пустыми строками или «полностью пустым пространством» (например, строки Windows с окончаниями строк в стиле «\ r \ n»), в то время как приведенное выше удаляет только файлы с пустыми строками и окончаниями строк в стиле Unix:

grep -v -e '^[[:space:]]*$' foo.txt
АРС
источник
Этот egrep будет работать только для файлов с нулем или 1 пробелом в строке, но не для файлов с 2 или более пробелами. Изменить ? к *.
Эд Мортон
4
Это должно быть grep -E -v, все после -eинтерпретируется как шаблон.
Джазпи
6
grep -v -e '^[[:space:]]*$' -e '^#' fileвыдаст вам все непустые строки без комментариев в скрипте или файле конфигурации (или любой тип файла, который использует хеш-символ для комментариев).
Palswim
-eMsgstr " Опция позволяет использовать регулярные выражения для сопоставления." Это очень вводит в заблуждение . -eявляется (POSIX-) определением для: This can be used to specify multiple search patterns, or to protect a pattern beginning with a hyphen (-).(из руководства ). Grep уже ожидает (базовое) регулярное выражение по умолчанию. Для этой модели, вы можете оставить в -eполностью: grep -v '^[[:space:]]*$' foo.txt.
Йети
74

Будь проще.

grep . filename.txt
Фрей Коннолли
источник
1
это дает мне все строки в файле
phuclv
2
@ LưuVĩnhPhúc Он должен выводить все строки в файле, кроме пустых строк.
Фрей Коннолли,
2
Это работает для меня на файлах из системы на основе Linux, но не на файлы из Windows. Предположительно из-за символов окончания строки в Windows.
Я голосую за это, хотя это не совсем решает проблему OP обработки файла с окончаниями строки Windows, но, поскольку у меня нет этой проблемы, это оказалось идеальным решением для меня.
Дэвид Z
1
Это идеальное решение. Просто и работало на Linux.
W00f
30

Использование:

$ dos2unix file
$ grep -v "^$" file

Или просто просто awk:

awk 'NF' file

Если у вас нет dos2unix, вы можете использовать такие инструменты, как tr :

tr -d '\r' < "$file" > t ; mv t "$file"
ghostdog74
источник
Не могу найти программу dos2unix. Это для Windows? команда ask тоже не работает.
узел ниндзя
просить? Нет, это awk.
иконоборчество
Хорошая мысль о преобразовании в окончания строк в стиле UNIX, иначе регулярные выражения могут работать не так, как ожидалось. Ничто здесь не работало для меня, пока я не преобразовал окончания строки.
Райан Х.
16
grep -v "^[[:space:]]*$"

The -v makes it print lines that do not completely match

===Each part explained===
^             match start of line
[[:space:]]   match whitespace- spaces, tabs, carriage returns, etc.
*             previous match (whitespace) may exist from 0 to infinite times
$             match end of line

Запуск кода

$ echo "
> hello
>       
> ok" |
> grep -v "^[[:space:]]*$"
hello
ok

Чтобы лучше понять, как и почему это работает, я рекомендую прочитать регулярные выражения. http://www.regular-expressions.info/tutorial.html

Sepero
источник
2
Как и почему это работает? Ваш ответ был бы намного лучше, если бы вы могли объяснить. Например, ваше регулярное выражение соответствует началу строки, затем одному или нескольким пробелам, используя стандарт POSIX, а затем конец строки, т.е. с помощью grep -v удаляются все строки, которые являются только пробелами. Правильно? Что происходит, если нет пробелов; это просто символ новой строки?
Бен
Как показывает мой пример, удаляется даже только пустая строка (первая строка). Я добавил больше информации, так что, надеюсь, это поможет. :)
Sepero
3

Я предпочитаю использовать egrep, хотя в моем тесте с подлинным файлом с пустой строкой ваш подход работал нормально (хотя в моем тесте без кавычек). Это тоже сработало:

egrep -v "^(\r?\n)?$" filename.txt
chryss
источник
Попробовал это. Пустые строки все еще отображаются. Может ли это быть потому, что файл был сделан в Windows?
узел ниндзя
3

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

grep -v "unwantedThing" foo.txt | cat -s

cat -s подавляет повторяющиеся пустые выходные строки.

Ваш вывод будет идти от

match1



match2

в

match1

match2

Три пустые строки в исходном выводе будут сжаты или «сжаты» в одну пустую строку.

Сенол Эрдоган
источник
2
awk 'NF' file-with-blank-lines > file-with-no-blank-lines
Тим
источник
2

Так же, как и предыдущие ответы:

grep -v -e '^$' foo.txt

Здесь grep -eозначает расширенную версию grep . '^ $' означает, что между ^ (начало строки) и $ (конец строки) нет никаких символов. «^» и «$» являются символами регулярных выражений.

Таким образом, команда grep -vнапечатает все строки, которые не соответствуют этому шаблону (между символами ^ и $ нет символов).

Таким образом, пустые пустые строки удаляются.

FatherMathew
источник
-eне означает "расширенная версия grep", может быть, вы запутались -E? В руководстве четко сказано, что -eпросто явно сказано, что шаблон следует. Поскольку шаблон начинается не с тире, и вы все равно определяете только один шаблон, вы можете с тем же успехом опустить его, поскольку по умолчанию grep ожидает один шаблон регулярного выражения: grep -v '^$' foo.txt(нет необходимости в расширенных функциях регулярного выражения). Также стоит отметить, что это не устраняет пустые строки в файле, а только то, что передается по выводу. Для этого случая, sed -iбудет правильным инструментом.
Йети
1

Я очень старался, но, похоже, это работает (при условии, \rчто кусает вас здесь):

printf "\r" | egrep -xv "[[:space:]]*"
MVDS
источник
Это работает, если я заменяю первую часть с выводом из файла.
узел ниндзя
0

Использование Perl:

perl -ne 'print if /\S/'

\S означает совпадение непустых символов.

Маджид Азими
источник
0

egrep -v "^ \ s \ s +"

egrep уже выполняет регулярное выражение, а \ s - это пробел.

+ Дублирует текущий шаблон.

^ Для начала

Jonni2016aa
источник
0

Использование:

grep pattern filename.txt | uniq
baitisj
источник
uniqуменьшит соседние пустые строки до одной пустой строки, но не удалит их полностью. Тем не менее, мне нравится пытаться использовать uniqтаким образом. Сортировка в первую очередь эффективно удалит все пустые строки, оставив только одну, но перестановка порядка строк может оказаться неприемлемой.
Зак Янг
Хорошая точка зрения. Это также изменит повторные строки. Я предполагаю, что мое решение вводит ошибки.
baitisj
0

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

[root@localhost ~]# cat /etc/sudoers | egrep -v '^(#|$)'
Defaults    requiretty
Defaults   !visiblepw
Defaults    always_set_home
Defaults    env_reset
Defaults    env_keep =  "COLORS DISPLAY HOSTNAME HISTSIZE INPUTRC KDEDIR
LS_COLORS"
root    ALL=(ALL)       ALL
%wheel  ALL=(ALL)       ALL
stack ALL=(ALL) NOPASSWD: ALL
lauc.exon.nod
источник
0

Это правда, что использование grep -v -e '^ $' может работать, однако оно не удаляет пустые строки, в которых есть 1 или более пробелов . Я нашел самый простой и простой ответ для удаления пустых строк - использование awk . Следующее является измененным немного от парней awk выше:

awk 'NF' foo.txt

Но так как этот вопрос касается использования grep, я собираюсь ответить на следующее:

grep -v '^ *$' foo.txt

Примечание : пробел между ^ и *.

Или вы можете использовать \ s для представления пустого пространства следующим образом:

grep -v '^\s*$' foo.txt
MarcT
источник