Не глючит ли sed, когда pattern является новой строкой для команды удаления?
Моя цель - напечатать содержимое файла до (и исключая) определенного шаблона, и я использую следующее, которое работает как ожидается (даже если шаблон ^$):
sed -n '/pattern/!p;//q' file
В своем стремлении сократить указанную выше команду (вы знаете, сохранить несколько байтов) я обнаружил, что могу "инвертировать" отмененную команду печати и вместо этого использовать удаление следующим образом:
sed '/pattern/d;//q' file
который снова работает, как ожидалось, за исключением случаев, когда /pattern/ относится к пустой строке, как в /^$/ и в этом случае он добавляет пустую строку к выводу, что странно.
Файл, очевидно, содержит пустую строку в моем случае, где я хочу разделить содержимое.
Есть идеи, почему это происходит? Является sed глючит для этого крайнего случая? (дополнительный //q немедленно завершает работу, чтобы сэкономить время обработки при использовании больших файлов)
sed --version возвращается sed (GNU sed) 4.5
2 ответа
После дальнейших исследований не существует выигрышного решения:
sed '/^$/,$d' file
это лучшее, что я мог найти с точки зрения компактности, с единственным недостатком, что он будет обрабатывать весь fileчто в некоторых случаях может быть нежелательным (например, большой)
sed '/^$/,$d;//q' file
добавление типичной команды выхода не помогает, так как более ранний диапазон уже охватывает весь file
sed '/^$/q' file
sed '/^$/Q' file
эти предложения, хотя и очень компактны, не идеальны (из-за дополнительного вывода / переносимости)
sed -n '/^$/q;p' file
это еще одно предложение, которое я также нашел самостоятельно в то же время, и это несколько хорошо, учитывая, что оно прекратит работу, как только будет найден паттерн, хотя я надеялся избавиться от -n вариант, с которого я начал все это...
С 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.