Заменить текст из строки выше в Vim - PullRequest
1 голос
/ 07 мая 2009

Как заменить первые десять символов строки, в которой эти десять символов соответствуют определенному шаблону, первыми десятью символами из строки выше?

Изменить: Было не ясно, если бы я попросил заменить первые десять символов, где совпадение может появиться где-нибудь в строке, так что, возможно, запишите в своем ответе, если он имеет дело с этим случаем (назовите этот случай B предполагаемый случай A?)

Ответы [ 6 ]

4 голосов
/ 07 мая 2009

Prehaps:

:%s/^\(.\{10}\)\(.*\n\)abcdefghij\(.*\)/\1\2\1\3/

Где 'abcdefghij' - строка из 10 символов во 2-й строке

3 голосов
/ 07 мая 2009
:2,$g/<pattern>/s/^.\{10}/\=strpart(getline(line(".")-1),0,10)
  • 2,$ - наш диапазон (поскольку первая строка не имеет предыдущей строки)
  • g// позволяет запустить команду в строках, соответствующих заданному шаблону.
  • s/^.\{10}/ заменит первые 10 символов строки
  • \= позволяет подставить результат выражения vim в :s//
  • line(".") - текущий номер строки
  • getline(line(".")-1) - текст предыдущей строки
  • strpart(getline(line(".")-1),0,10) - первые 10 символов предыдущей строки

Например, 2,$g/frog/s/^.\{10}/\=strpart(getline(line(".")-1),0,10) изменится:

<b>I like eat</b>ing mangos
<b>before fry</b>ing frogs legs
<b>I wish I h</b>ad a puppy
<b>She gave D</b>ad a frog

На это:

<b>I like eat</b>ing mangos
<b>I like eat</b>ing frogs legs
<b>I wish I h</b>ad a puppy
<b>I wish I h</b>ad a frog
3 голосов
/ 07 мая 2009

Примерно так будет работать:

%s/^.\{10\}/\=strpart(get(getbufline("", line(".")-1), 0, ""), 0, 10)/

где ^.\{10\} - ваш фактический шаблон.

%s/                      # substitute all lines matching…
^.\{10\}                 # your pattern
/                        # …with…
\=                       # an expression:
strpart(                 # gets the part of a string
  get(                   # gets an element of a list
    getbufline(          # gets a list of lines from the current buffer
      "", line(".")-1)   # getbufline() the line before the current line
  , 0, "")               # get() first line in buffer, default to ""
, 0, 10)                 # strpart() first ten characters
/                        # …end of substitution
2 голосов
/ 07 мая 2009

Если у меня такое сложное действие, я обычно записываю макрос с помощью команды q. Что-то вроде (не проверено):

/<pattern>
qq
10x
k
10yl
j
P
n
q

И затем повторно выдают этот макрос как @q, возможно, с префиксом count.

1 голос
/ 07 мая 2009

Использование только движений vim и рывков / вставок .. Учитывая содержимое файла ..

1234567890abcdef
qwertyuiopasdfgh

При наведении курсора на q, 10x файл становится:

1234567890abcdef
asdfgh

Переместите курсор на первую строку (используйте k), затем выполните 10yl (вернуть 10 символов вправо)

Затем вернитесь назад на одну строку, j, и вставьте P (верхний регистр, чтобы вставить под курсором), и файл станет:

1234567890abcdef
1234567890asdfgh

Короче говоря, начиная с курсора на q:

10xk10yljP

.. которую вы можете вставить или назначить макросу

Было бы короче, если бы был очевидный ярлык для вставки путем перезаписи, но я не мог найти такую ​​вещь

Еще один вариант - невероятно выглядящий поиск / замена регулярных выражений.

Визуальная строка, выберите две целевые строки и выполните следующий поиск и замену:

:'<,'>s/\(\(.\{10\}\).*\)\n\(.\{10\}\)\(.*\)$/\1\r\2\4/

В основном хватается ..

  • \1 - вся первая строка
  • \2 - первые 10 символов (во вложенной группе)
  • перевод строки
  • \3 - первые десять символов второй строки
  • \4 - остаток второй строки

Затем он строит две строки как \1\n\2\4 - полная первая строка, разрыв строки, первые 10 символов первого, остаток второй

1 голос
/ 07 мая 2009

Вы можете использовать поиск и заменить:

:7,9 s/foo/bar/c

Этот пример ищет в строке 7-9 каждое вхождение 'foo' и заменяет его на 'bar', запрашивая подтверждение при каждом попадании. Если вы не хотите подтверждать, опустите c в конце. Выберите диапазон так, как считаете нужным, и вы получите то, что хотите

...