Я смотрел на этот вопрос, а потом удивлялся, как мне реализовать свой ответ, использующий
sed
исключительно
POSIX
ex
.
Хитрость заключается в том, что хотя sed
я могу сравнить пространство удержания с пространством шаблона, чтобы увидеть, являются ли они в точности эквивалентными (с
G;/^\(.*\)\n\1$/{do something}
), я не знаю способа выполнить такой тест ex
.
Я знаю, что в Vim я мог бы Y
прикрепить первую строку, а затем набрать,
:2,$g/<C-r>0/d
чтобы почти выполнить то, что я указываю, но если первая строка содержит что-либо, кроме очень простого буквенно-цифрового текста, это действительно становится случайным, поскольку строка выводится как
регулярное выражение , а не просто строка для сравнения. (И если первая строка содержит косую черту, остальная часть будет интерпретирована как команда!)
Поэтому, если я хочу удалить все строки в myfile
этой строке , идентичные первой строке, но не удалить первую строку, как я могу это сделать, используя ex
? В этом отношении, как я мог сделать это, используя vi
?
Есть ли способ POSIX удалить строку, если она точно совпадает с другой строкой?
Возможно, что-то вроде этого воображаемого синтаксиса:
:2,$g/**lines equal to "0**/d
<C-r>0
очень хорошим. Я не уверен, что вы могли бы добиться большего успеха только с помощью команд Ex, потому что вы должны защищать специальные символы. Без ограничения, совместимого с POSIX, я думаю, что вы бы использовали очень номагический переключатель, \V
а затем защитили бы обратную косую черту (потому что она сохраняет свое особое значение даже с помощью \V
) с помощью escape()
функции, второй аргумент которой является строкой, содержащей все символы, которые вы хотите экранировать / защитить ,
:execute '2,$g/\V' . escape(getline(1), '\/') . '/d'
Или вы можете использовать другой символ для разделителя шаблонов, например точку с запятой. В этом случае вам не нужно защищать косую черту в шаблоне. Было бы что-то вроде::execute '2,$g;\V' . escape(getline(1), '\') . ';d'
sed
тоже очень хорош. С Vim вы часто делегируете определенные специальные задачи другим программам, и sed
, вероятно, хороший пример этого. Кстати, вам не нужно запускать sed
весь буфер. Если вы хотите запустить его только на части буфера, вы можете указать диапазон. Например, если вы хотите , чтобы отфильтровать только строки между 50 и 100, вы можете набрать: :50,100!<your sed command>
.
:execute '2,$g/\V' . escape(getline(1), '\') . '/d'