Shell: простой способ получить все строки перед первой пустой строкой

Какая лучшая команда оболочки для вывода строк файла до тех пор, пока вы не встретите первую пустую строку? Например:

output these
lines

but do not output anything after the above blank line
(or the blank line itself)

ок? что-то другое?


person Peter    schedule 21.10.2009    source источник


Ответы (7)


Еще awk:

awk -v 'RS=\n\n' '1;{exit}'

Еще sed:

sed -n -e '/./p;/./!q'
sed -e '/./!{d;q}'
sed -e '/./!Q'   # thanks to Jefromi

Как насчет непосредственно в оболочке?

while read line; do [ -z "$line" ] && break; echo "$line"; done

(Или printf '%s\n' вместо echo, если ваша оболочка глючит и всегда обрабатывает escape-последовательности.)

person ephemient    schedule 21.10.2009
comment
Хороший айкинг! Второй sed можно сократить до '/./!Q'Q завершает работу немедленно, без автопечати. +1 - person Cascabel; 22.10.2009
comment
Я пробовал некоторые тайминги: '/./!Q' 2,5 с; '/./!{d;q}' 5,5 с; '/^$/Q' 7,5 с. - person Cascabel; 22.10.2009
comment
Обратите внимание, что BSD sed (который устанавливается в OSX по умолчанию) не поддерживает модификаторы q или Q. - person dimo414; 01.03.2017

С СЭД:

sed '/^$/Q' <file>

Редактировать: sed намного быстрее. См. Ответ ephemient для самой быстрой версии.

Чтобы сделать это в awk, вы можете использовать:

awk '{if ($0 == "") exit; else print}' <file>

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

person Cascabel    schedule 21.10.2009
comment
Обратите внимание, что BSD sed (который устанавливается в OSX по умолчанию) не поддерживает модификаторы q или Q. - person dimo414; 01.03.2017

Awk-решение

awk '/^$/{exit} {print} ' <filename>
person Vereb    schedule 21.10.2009
comment
1 короче, чем запись {print}, и делает то же самое. - person ephemient; 22.10.2009

Вот решение с использованием Perl:

#! perl

use strict;
use warnings;

while (<DATA>) {
    last if length == 1;
    print;
}

__DATA__
output these
lines

but don't output anything after the above blank line
(or the blank line itself)
person chardin    schedule 21.10.2009
comment
perl -pe 'выйти, если m/^$/' (имя файла) - person Joe; 22.10.2009
comment
Джо, у тебя хорошее решение на Perl. Хотел бы я подумать об этом. - person chardin; 22.10.2009
comment
@Joe: m избыточен, см. мой ответ stackoverflow.com/questions/1603389/ - person jfs; 22.10.2009

Пара острот Perl

$ perl -pe'last if /^$/' file..

$ perl -lpe'last unless length' file..
person jfs    schedule 21.10.2009

Другое решение Perl:

perl -00 -ne 'print;exit' file
perl -00 -pe 'exit if $. == 2' file
person glenn jackman    schedule 22.10.2009

person    schedule
comment
Вероятно, будет немного понятнее написать это как: sed -e '/^$/,$d' <file>. Кроме того, если у вас есть огромные файлы (или их много), может возникнуть проблема с чтением всего файла. В остальном красиво и коротко! - person Cascabel; 22.10.2009
comment
Я добавил в свой ответ решение sed, которое не читает весь файл. - person Cascabel; 22.10.2009
comment
Мне также нравится решение ephemient sed -e '/./!Q'. - person themis; 22.10.2009
comment
Помимо простого предоставления кода, некоторое объяснение того, как это работает, помогло бы нам, новичкам. - person Francois Botha; 12.02.2014
comment
Это круто. Я изменил его следующим образом, чтобы обрабатывать пустую строку с пробелами: sed -e '/^\s*$/,$d' - person Jason Stangroome; 17.10.2014