Дублікати рядків, що починаються з "x", замінюючи "x" у дублікаті на "y"?


9

У мене є файл із такою схемою:

foo 111
baz
foo 222
baz
foo 333
baz

в яку потрібно перетворити

foo 111
bar 111
baz
foo 222
bar 222
baz
foo 333
bar 333
baz

Отже, дублюйте всі рядки, що починаються з foo, і змінюйте лише fooв дублікаті, але залиште решту рядка (що відрізняється в кожному випадку) недоторканим. Як це зробити?


Якщо ви не зв'язані з пеклами згенерування, макрос буде добре. Насправді це не так вже й багато в таких простих випадках, але якщо у вас є щось трохи складніше, це дуже коректна альтернатива.
PhilippFrank

Відповіді:


19

Ось вам:

:g/foo/t.|s//bar

Декомпозиція:

:g/foo/    " start a global command applied on all lines matching 'foo'
t.         " duplicate the current line (the cursor is now on the new line)
|          " chain a new command
s//bar     " substitute the last searched element with 'bar'

Оскільки gкоманда оновить шаблон пошуку, то ви можете опустити шаблон для заміни в команді-заміннику. (ref:, :h :gпошук search pattern).


Старіша версія:

:g/foo/norm! yyp:s/foo/bar^M

Декомпозиція:

:g            start a global command
/foo/         apply only on lines having 'foo'
norm!         execute a normal command
yyp           duplicate the line
:s//bar       replace foo with bar on the line (the duplicated one)
^M            add enter to execute the substitution

Щоб вставити ^Mпрес Ctrl+vі enter.

Примітка . Спочатку я придумав "старішу" версію, перш ніж дізнався про tкоманду. Я залишу його, але не рекомендую використовувати його. Перший - чистіший і простіший.


Вирішена, «простіша версія» спрацювала чудово. Перша версія, проте, призвела до того, що повторюваний рядок все ще починається з foo....
LB7979

дивно, ти ввійшов, ^Mяк я пояснив?
nobe4

Мій поганий, не так добре читав. Перше рішення також працює!
LB7979

Я не знаю, чому ви взагалі турбуєтесь, включаючи складну версію. Простіша версія ... простіша. ;) (Не кажучи вже про сумісність з POSIX.) Чому б не поставити його на перше місце?
Wildcard

1
Спочатку я придумав першу версію, яка була для мене більш природною, бо на той час я не знала t, а потім додала другу. Я поміняю порядок, ви праві. Як щодо першого, який є POSIX?
nobe4

1

Я постійно займаюся подібними справами і просто займаюся чимось подібним %s/^foo \(.*\)/foo \1\rbar \1/(частково тому, що я також роблю багато подібних завдань, які неможливо перетворити на щось розумне за допомогою функції копіювання і на сьогоднішній день \(.*\)є частиною моєї м'язової пам’яті).

Я підозрюю, що це не сумісно з POSIX (він не працює на інших VI-клонах), але використання ^M( C-VReturn) замість цього, \rздається, працює на більшості інших клонів vi.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.