Моя цель состоит в том, чтобы напечатать содержимое файла до (и исключая) определенного шаблона, и я использую следующее, которое работает как ожидалось (даже когда шаблон равен ^$):

sed -n '/pattern/!p;//q' file

В моем стремлении сократить указанную выше команду (вы знаете, сохранить несколько байтов) я обнаружил, что могу "инвертировать" отмененную команду печати и вместо этого использовать удаление следующим образом:

sed '/pattern/d;//q' file  

который снова работает как положено, за исключением случаев, когда /pattern/ ссылается на пустую строку, как в /^$/ и в этом случае он добавляет пустую строку к выводу, что странно.

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

Есть идеи, почему это происходит? Является ли sed глючит для этого крайнего случая? (дополнительный //q завершает работу немедленно, чтобы сэкономить время обработки при использовании больших файлов)

sed --version возвращает sed (GNU sed) 4.5

2 ответа2

2

С GNU sed вы можете запустить

sed '/pattern/Q' file

Команда q печатает пространство шаблона перед выходом, команда Q завершает работу без вывода сообщений.

Я думаю, что отрицаемая команда !p избегает q чтобы напечатать пространство шаблона.

sed -n '/pattern/!p;//q' file  

Опция -n позволяет избежать q для печати пространства шаблона. Другие строки печатаются, потому что адрес отменяется, поэтому команда p применяется ко всем строкам, кроме тех, которые содержат /pattern/ . Другой способ написать это будет

sed -n '/pattern/q;p' file

При совпадении с pattern выйдите (без печати из-за опции -n ). Все остальные строки печатают.

В этом другом сценарии команда d удаляет все пространство шаблона и переходит непосредственно к началу сценария sed с загруженной новой строкой ввода.

sed '/pattern/d;//q' file  

edit- В этом случае я думаю, что //q никогда не будет достигнуто, когда есть совпадение.

echo -e 'one\ntwo\nthree\n\nfour\n\n'|sed '/^$/d;//q'
one
two
three
four

Возможно, строка не пуста, запустите cat -vet file чтобы увидеть, есть ли что-то.

В новой версии sed 4.7 появилась новая опция --debug , очень полезно посмотреть, как работает sed.

0

После дальнейших исследований не существует выигрышного решения:

sed '/^$/,$d' file

это лучшее, что я мог найти с точки зрения компактности, с единственным недостатком, что он будет обрабатывать весь file , что в некоторых случаях может быть нежелательным (например, большой)

sed '/^$/,$d;//q' file

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

sed '/^$/q' file
sed '/^$/Q' file

эти предложения, хотя и очень компактны, не идеальны (из-за дополнительного вывода / переносимости)

sed -n '/^$/q;p' file

это еще одно предложение, которое я также нашел самостоятельно в то же время, и это несколько хорошо, учитывая, что оно прекратит работу, как только будет найден шаблон, хотя я надеялся избавиться от опции -n которой я начал со всем этим ...

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .