Не глючит ли 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.