Jai un fichier texte comme celui-ci (en utilisant gVim sous Windows)
foo bar baz quux corge grault garply waldo fred plugh [...150 more lines...] xyzzy thud
Je souhaite ajouter un numéro à chaque ligne du fichier. Ne pas utiliser :set number
, mais pour ajouter le nombre sous forme de texte précédant chaque ligne, comme suit, afin que le numéro fasse partie du fichier.
1. foo bar baz quux 2. corge grault garply 3. waldo fred plugh [...~150 more lines...] 155. xyzzy thud
Commentaires
Réponse
De manière purement Vim:
:%s/^/\=line(".").". "
Explication:
:%s/^/ " the substitution will be applied to the beginning of every line \= " the rest of the replacement part is an expression line(".").". " " the expression returns the current line number concatenated with a dot and a space
Voir :help \=
et :help line()
.
Utiliser une expression dans la pièce de rechange est très puissant et FWIW est un très bon point dentrée pour vimscript.
Commentaires
- Comment puis-je ajouter cette commande très utile à un keymap dans vimrc?
- Pour accéder à la rubrique daide de vim pour la substitution:
:help sub-replace-expression
Réponse
Une bonne chose à propos des macros Vim est quelles peuvent recurse (elles peuvent sappeler ):
- Effacer le registre q:
qqq
- Ajouter le numéro à la première ligne:
ggI1.
(noubliez pas lespace!) - Revenez au début de la ligne et commencez à enregistrer une macro:
0qq
- Copiez le numéro:
- Descendez dune ligne et collez le numéro:
+P
- Revenez au début de la ligne et incrémentez le nombre:
0<c-a>
- Revenez au début de la ligne (pour que la macro ne casse pas lorsquelle arrive à doubler les chiffres!):
0
- Appelez la macro une fois, pour la rendre récursive. À ce stade, il ny a toujours rien dans le registre q, donc rien ne se passera:
@q
. - Enregistrez la macro:
q
- Appelez la macro une fois de plus et regardez les étincelles voler !:
@@
La macro va puis continuez à linvoquer jusquà ce quil atteigne la fin du fichier.
Vous pouvez utiliser lastuce des macros récursives pour de nombreux autres problèmes similaires, cest donc un bon moyen den être conscient.
Si vous ne voulez pas utiliser une macro récursive pour une raison quelconque, vous pouvez omettre les étapes 1 et 8, et utiliser un count pour exécuter la macro plusieurs fois, par exemple 100@q
exécutera la macro q
100 fois.
Commentaires
- Des trucs puissants, je mincline devant votre maîtrise. Les macros sont comme de la magie noire pour moi …
- @ropata, une macro nest quune séquence de commandes en mode (principalement) normal.
- @romainl Je pense que ‘ vaut mieux le considérer comme une séquence de frappes .
- @Rich, cela peut être une séquence de beaucoup de choses, y compris des commandes ex.
- @romainl Oui, cest ‘ pourquoi je pense quil est préférable de ‘ de le considérer comme des touches. Il lit exactement ce que vous tapez sur le clavier (y compris, comme vous le dites, les commandes ex), comme si vous aviez tout saisi manuellement.
Réponse
Jaime utiliser la commande globale vim pour accomplir des tâches comme celle-ci. Cela sapplique à lajout dune itération au début dune ligne ou à la modification dun symbole dans le texte. Cela semble plus compliqué que les autres solutions, mais cest un modèle assez flexible à utiliser lorsque vous lavez à portée de main, et est facile à modifier sans beaucoup de réflexion.
Tout dabord, choisissez votre plage (quelles lignes vous veulent appliquer cela). Jutilise habituellement des marques (par ex.ma
sur la première ligne et mb
sur la seconde, mais vous pouvez également utiliser des numéros de ligne ou une sélection visuelle), puis entrez une modification de la commande suivante (actuellement modifiée pour votre cas dutilisation)
:let i=1|"a,"bg/^/s/^/\=i.". "/|let i=i+1
Deconstruction
:let i=1
Cela configure la variable i
avec une valeur de départ. Habituellement, les listes commencent par 1, donc je « m met i à 1.
|
La barre lance une nouvelle commande
"a,"b
Ceci définit la plage de la commande suivante. Je passe de la marque a
à la marque b
, qui serait défini sur la première et la dernière ligne de votre liste.
g/^/
Ceci est la commande globale. Il recherche dans le fichier (ou la plage) une expression régulière donnée et exécutera le reste de la ligne de commande sur chacune des lignes qui correspondent. Je « fais correspondre chaque ligne en recherchant » début de ligne « . Si vous aviez du texte comme
Item some txt other text Item second item whatever Item third
et que vous ne voulez mettre ces libellés devant Item
et ignorez les autres lignes, faites g/Item/
ou g/^Item/
à la place (en supposant le texte littéral de lélément )
s/^/\=i.". "/
Ceci exécute lexpression régulière pour remplacer le début de la ligne par la valeur de i
concaténée avec a .
. Généralement, vous pouvez faire cela pour nimporte quoi (remplacez le libellé Item
par le nombre, par exemple).
|let i=i+1
Même si la barre lance une nouvelle commande, elle configure une deuxième commande à exécuter dans la commande globale, au lieu de lexécuter après la fin du global. Le résultat est que nous incrémentons i
avant que la ligne suivante ne soit traitée par g. Voici un autre lieu de flexibilité. La modification de i peut être nimporte quoi (incre par 2, appelez une fonction qui génère lélément suivant de la séquence de Fibonacci, peu importe).
Réponse
Ajouter des nombres à toutes les lignes
Il « est possible dutiliser :%!nl -ba
ou :%!cat -n
qui ajouteront des numéros de ligne à toutes les lignes.
Sous Windows, vous « Je dois installer Cygwin / MSYS / SUA.
Ajouter des numéros aux lignes sélectionnées
Pour ajouter des numéros uniquement pour les lignes sélectionnées, veuillez les sélectionner dans mode visuel ( v et curseurs), puis une fois terminé – exécutez la commande: :%!nl
(ignorer les lignes vides) ou :%!cat -n
(lignes vides incluses).
Formatage
Pour supprimer les espaces supplémentaires, sélectionnez-les dans le bloc visuel ( Ctrl + v ) et supprimez-les ( x ).
Pour ajouter des caractères (.
, :
, ) après les nombres, sélectionnez-les dans le bloc visuel ( Ctrl + v ), puis ajoutez le caractère ( A , tapez le caractère, puis terminez par Echap ).
Commentaires
- Cela ne donne pas la même mise en forme que celle donnée dans la question. Cependant, jaime la simplicité de la solution.
- @KarlYngveLerv å g Merci, inclus cela dans la réponse.
Réponse
Une modification de la réponse de romainl « :
:%s/^\(\d\+\. \)\?/\=line(".").". "
Cela ne va pas simplement ajouter les numéros de ligne, mais aussi remplacer les numéros de ligne sortants s’ils sont déjà là. De, si vous « avez inséré une ligne à mi-chemin, il renumérotera tout comme prévu.
Cela fonctionne en remplaçant nimporte quel nombre suivi dun. Et un espace au début de la ligne par un nouveau nombre . Cela va évidemment casser si vous avez une ligne qui commence déjà par ce modèle, alors utilisez-la avec réflexion.
La partie ajoutée:
-
^
– Début de ligne -
\(
– Démarrer un nouveau sous-groupe -
\d\+
– Faire correspondre un chiffre une ou plusieurs fois -
\.
– Faire correspondre un point (
.
) et un espace.
-
\)
– Fin du sous-groupe -
\?
– Rendre le groupe facultatif, pour quil fonctionne comme avant sil ny a pas encore de numéro sur cette ligne.
Indice bonus :
Pour supprimer les numéros de ligne, vous pouvez utiliser le même modèle avec la partie repalce vide:
:%s/^\(\d\+\. \)\?//
Réponse
I1. <esc>^qqyWjP^<C-a>q
Cela numérote les deux premières lignes et vous pouvez appuyer sur @q
pour numéroter les lignes suivantes (ou tapez ex. 18@q
si vous voulez numéroter 20 lignes au total).
Explication:
I1. <esc> Number the first line hqq Go back to the start of the line and start recording a macro yWjP Copy the line number to the next line ^<C-a> Increment the next line"s line number q Finish recording
Lavantage de ceci est quil ne nécessite aucune commande externe, ce qui est utile si vous « re travailler avec Vim sous Windows, par exemple.
Commentaires
- Après avoir tapé
1. <esc>h
vous êtes sur le deuxième colonne, pas la première colonne. Je remplaceraish
par0
, après quoi je pense que votre solution devrait être très bonne. - @KarlYngveLerv å g Oups, cétait une faute de frappe. Merci, corrigé.
- Aucun problème. Cependant, vous navez toujours pas mis à jour lexplication. Aussi: sur de nombreux claviers,
^
attend un deuxième caractère afin de permettre des combinaisons de frappe comme^a -> â
. Je suis toujours d’accord que c’est la meilleure solution, mais je pense que cela doit également être mentionné.
Réponse
I Je pense que la réponse choisie est la meilleure, mais dans un esprit de variété, je vais proposer une alternative en utilisant un programme externe:
:%!cat -n
Cela filtrera tout votre tampon (comme indiqué par %
) via le programme externe, cat
, où -n
flag ajoute un numéro de ligne à chaque ligne dentrée.
Ceci, bien sûr, nécessite que vous ayez cat
installé, ce qui est vrai pour (probablement) tous les Unix -like systèmes.
Consultez :help :range!
pour plus de détails sur le filtrage via des programmes externes.
Commentaires
- Je me rends compte que le demandeur utilise gVim sous Windows, donc cette solution ne fonctionnera probablement pas ‘ là-bas. Cependant, je pense que cela offre encore une opportunité pour les autres t o en tirer des leçons.
- Si vous ‘ avez installé
msysgit
et lavez ajouté à votre PATH (IIRC il ‘ est une option dinstallation), cette solution devrait également fonctionner sous Windows. -
cat -n
nest pas POSIX, maisnl
lest, il peut donc sagir dun meilleure option.
Réponse
Une solution un peu hackish pourrait être la suivante (tout ce qui est écrit entre < et> doivent être insérés après avoir appuyé sur Ctrl + v ):
:%normal :redir @"<Enter>:-=<Enter>:redir END<Enter>I<C-R>".<Tab><Esc>kdd
Déconstruction
:%normal {commands}
exécute la commande en mode normal sur chaque ligne spécifiée par la plage, dans ce cas chaque ligne
:redir @"
redirige chaque sortie faite par les commandes ex vers le tampon sans nom.
:.=
est une commande ex qui affiche la ligne courante numéro (avec un saut de ligne précédent malheureusement)
:redir END
arrête la redirection vers le tampon sans nom
I<C-R>".<Tab><Esc>
insère le contenu du tampon sans nom avec un. et une tabulation au début de chaque ligne et quitte le mode insertion.
kdd
remonte dune ligne et supprime la nouvelle ligne qui est le résultat de:. = commande.
awk
est probablement loutil pour ce travail. Mais je suis ‘ sous Windows (soupir).cat
ounl
, qui peuvent faire des lignes numériques, mais ne sont pas ‘ t généralement disponible sous Windows (comme OP lindique à partir de son commentaire surawk
). Les deux principales solutions sont le pur Vim. Enfin, toutes les lignes contre un para est juste une question de sélection de plage. Ce nest clairement pas un gros problème.