Remplacer le texte de la ligne ci-dessus dans Vim
Question
Comment puis-je remplacer les dix premiers caractères d'une ligne lorsque ces dix caractères correspondent à un motif particulier avec les dix premiers caractères de la ligne ci-dessus?
Modifier: Il n’était pas clair si je demandais de remplacer les dix premiers caractères pour lesquels la correspondance pouvait apparaître n'importe où dans la ligne. Vous pouvez donc peut-être ajouter une note dans votre réponse si elle traite de ce cas (appelez ce cas B et le cas prévu A?)
La solution
Prehaps:
:%s/^\(.\{10}\)\(.*\n\)abcdefghij\(.*\)/\1\2\1\3/
Où 'abcdefghij' est la chaîne de 10 caractères sur la 2ème ligne
Autres conseils
Quelque chose comme ça fonctionnerait:
%s/^.\{10\}/\=strpart(get(getbufline("", line(".")-1), 0, ""), 0, 10)/
où ^. \ {10 \}
est votre motif actuel.
%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, $
est notre plage (car la première ligne n'a pas de ligne précédente) -
g //
vous permet d'exécuter une commande sur des lignes correspondant à un modèle donné. -
s / ^. \ {10} /
remplacera les 10 premiers caractères d'une ligne -
\ =
vous permet de substituer le résultat d'une expression vim dans un: s //
-
ligne (".)
est le numéro de ligne actuel -
getline (ligne (". ") - 1)
est le texte de la ligne précédente -
strpart (getline (ligne (")" - 1), 0,10)
sont les 10 premiers caractères de la ligne précédente
Par exemple, 2, $ g / frog / s / ^. \ {10} / \ = strpart (getline (ligne (")" - 1), 0,10)
va changer:
I like eating mangos before frying frogs legs I wish I had a puppy She gave Dad a frog
À ceci:
I like eating mangos I like eating frogs legs I wish I had a puppy I wish I had a frog
Si j'ai une action complexe comme celle-là, j'enregistre habituellement une macro à l'aide de la commande q
. Quelque chose comme (non testé):
/<pattern>
qq
10x
k
10yl
j
P
n
q
Ensuite, relancez cette macro sous la forme @q
, éventuellement précédée d'un nombre.
Vous pouvez utiliser rechercher et remplacer:
:7,9 s/foo/bar/c
Cet exemple recherche les lignes 7 à 9 pour chaque occurrence de "foo" et les remplace par "bar", demandant une confirmation pour chaque résultat. Si vous ne voulez pas confirmer, laissez tomber le c à la fin. Choisissez la gamme que vous souhaitez et cela vous mènera où vous le souhaitez
En utilisant uniquement les mouvements et les mouvements vancé / collé de vim .. Compte tenu du contenu du fichier de ..
1234567890abcdef
qwertyuiopasdfgh
Avec le curseur sur q, 10x
, le fichier devient:
1234567890abcdef
asdfgh
Déplacez le curseur sur la première ligne (utilisez k
pour le faire), puis faites 10yl
(yank 10 caractères, à droite)
Descendez ensuite d'une ligne, j
, et collez P
(majuscule, pour coller sous le curseur) et le fichier devient:
1234567890abcdef
1234567890asdfgh
En bref, en commençant par le curseur sur q:
10xk10yljP
Ce serait plus court s'il y avait un raccourci évident à coller par écrasement, mais je ne pouvais pas trouver une telle chose
Une autre option est une recherche / remplacement regex incroyablement obscure ..
Visual-line sélectionne les deux lignes cibles et lance la recherche-remplacement suivante:
:'<,'>s/\(\(.\{10\}\).*\)\n\(.\{10\}\)\(.*\)$/\1\r\2\4/
En gros, il attrape ..
-
\ 1
- la première ligne entière -
\ 2
- les 10 premiers caractères (dans un groupe imbriqué) - un saut de ligne
-
\ 3
- les dix premiers caractères de la deuxième ligne -
\ 4
- le reste de la deuxième ligne
Ensuite, il construit les deux lignes comme suit: \ 1 \ n \ 2 \ 4
- première ligne complète, saut de ligne, 10 premiers caractères du premier, reste de la seconde