Вопрос

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

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

Это было полезно?

Решение

Предварительные варианты:

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

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

Другие советы

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

%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,$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) изменится:

Я люблю поестьing mangos
перед обжариваниемing frogs legs
Я хотел бы, чтобы яad a puppy
Она дала Дad a frog

К этому:

Я люблю поестьing mangos
Я люблю поестьing frogs legs
Я хотел бы, чтобы яad a puppy
Я хотел бы, чтобы яad a frog

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

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

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

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

:7,9 s/foo/bar/c

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

Используя только движения 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 символов первой, остаток второй

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top