Я дивився на це питання, а потім цікавився, як я можу реалізувати свою відповідь, яка використовує
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'