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