Вопрос
Как я могу заменить первые десять символов строки, где эти десять символов соответствуют определенному шаблону, на первые десять символов из строки выше?
Редактировать:Было неясно, просил ли я заменить первые десять символов, где совпадение может появиться в любом месте строки, поэтому, возможно, сделайте пометку в своем ответе, если он касается этого случая (назовите этот случай 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 символов первой, остаток второй