Замените n-е вхождение слова в vim
Я видел другие вопросы, связанные с нахождением n-го вхождения слова/шаблона, но я не мог найти, как вы на самом деле замените n-е вхождение шаблона в vim. Там очевидный способ жесткого кодирования всех вхождений, таких как
:s/.*\(word\).*\(word\).*\(word\).*/.*\1.*\2.*newWord.*/g
Есть ли лучший способ сделать это?
Ответы
Ответ 1
Вы можете сделать это немного проще, используя несколько поисков. Пустой шаблон в команде :s/pattern/repl/
означает замену последнего результата поиска.
:/word//word//word/ s//newWord/
or
:/word//word/ s/word/newWord/
Затем вы можете повторить это несколько раз, выполнив @:
или даже [email protected]:
, чтобы повторить команду еще 10 раз.
В качестве альтернативы, если бы я делал это в интерактивном режиме, я бы сделал что-то вроде:
3/word
:s//newWord/r
Это найдет третье вхождение слова, начинающегося с курсора, а затем выполнит замену.
Ответ 2
Для информации
s/\%(\(pattern\).\{-}\)\{41}\zs\1/2/
также работает, чтобы заменить 42-е место. Тем не менее, я предпочитаю решение, данное Джоном Кугельманом, которое более просто - даже если оно не будет ограничиваться текущей строкой.
Ответ 3
Замените каждое N th появление PATTERN в строке с REPLACE.
:%s/\(\zsPATTERN.\{-}\)\{N}/REPLACE/
Ответ 4
Это отвечает на ваш реальный вопрос, но не ваши намерения.
Вы спросили о замене n-го вхождения слова (но, казалось, означали "внутри строки" ). Вот ответ на вопрос, как задавали, если кто-то найдет его, как я сделал =)
Для странных задач (например, для замены каждого 12-го появления "собака" на "попугай" ) мне нравится использовать рекурсивные записи.
Сначала запишите запись в @q
qqq
Теперь запустите новую запись в q
qq
Затем вручную сделайте то, что вы хотите сделать (используя пример выше, замените 12-е появление "собаки" на "попугай" ):
/dog
nnnnnnnnnnn
удалить "собаку" и войти в нее
diwi
тип попугая
parrot
Теперь воспроизводите текущую пустую запись "@q"
@q
который ничего не делает.
Наконец, прекратите запись:
q
Теперь ваша запись в @q вызывает себя в конце. Но поскольку он вызывает запись по имени, он больше не будет пустым. Итак, вызовите запись:
@q
Он воспроизведет запись, а затем, в конце, как последний шаг, снова воспроизведет. Он будет повторять это до конца файла.
TL;DR;
qq
q
/dog
nnnnnnnnnnndiwiparrot<esc>
@q
q
@q
Ответ 5
Хорошо, если вы сделаете /gc
, тогда вы можете подсчитать количество раз, когда он просит вас подтвердить, и продолжите замену, когда вы доберетесь до n-го: D