En fait, vous vous trompez Michael. Cela fonctionne parfaitement car le VI arrêtera d'exécuter la macro dès qu'elle atteindra la fin du fichier. Vous pouvez très facilement l'essayer avec l'exemple ci-dessus.
rui
1
Eh bien, comme toute macro, vous devez faire les choses correctement la première fois, mais après cela, vous pouvez appliquer à n'importe quel fichier en tapant simplement 10000 @ q. Quoi qu'il en soit, je pense que c'est juste une question de goûts, donc je ne vais définitivement pas lancer un débat philosophique. :)
rui
3
Je préfère utiliser «macro». En utilisant la macro, vous «décrivez» comment vous résoudriez une tâche particulière et laissez VIM la répéter pour vous. RUI, je préférerais utiliser «j» au lieu de la touche fléchée.
Un moyen élégant (et efficace) d'accomplir la tâche consiste à appeler la :+deletecommande en supprimant la ligne qui suit la ligne actuelle, sur chaque ligne à l'aide de la :globalcommande:
Pourquoi cette réponse n'a-t-elle pas reçu plus de votes? C'est tellement propre et simple. Vous pouvez également supprimer la première ligne et exécuter la commande ci-dessus pour supprimer toutes les lignes impaires.
Usagi
3
@Usagi: Merci! Je ressens la même chose à ce sujet. Et oui, vous avez tout à fait raison, :1d|g/^/+dsupprime les lignes impaires.
ib.
@Usagi L'autre réponse a été choisie comme «meilleure réponse» 2 ans avant que sa réponse n'apparaisse. De plus, bien que ce soit une solution plus élégante, elle aurait pu être écrite d'une manière plus utile (c'est-à-dire qu'il n'y a aucune mention de ce que fait ^, alors que la macro est facile à comprendre pour tout le monde).
user1271772
3
Désolé, mais sans une explication sur la façon dont cette commande exécute le comportement souhaité, je ne la voterais pas, et préférerais plutôt la réponse acceptée, car je comprends comment elle atteint l'objectif. C'est la différence entre donner un poisson à un homme et lui apprendre à pêcher.
Gabe
3
Je ne sais pas, cette réponse m'a fait sortir et apprendre à pêcher avec la commande: g (c'est-à-dire qu'elle m'a fait google cette page - vim.wikia.com/wiki/Power_of_g ).
snetch le
67
Nous pouvons utiliser :normalou :normexécuter des commandes de mode normal données. La source.
Cette réponse ne retient pas suffisamment l'attention, peut-être à cause du manque d'explications à la fois ici et sur la feuille de triche liée et désordonnée. la commande norm exécute les commandes de mode normal équivalentes aux lettres qui la suivent. Donc, ici, il exécute j pour descendre d'une ligne et dd pour le supprimer. Ceci est généralisable à la Xème ligne en ajoutant plus de «j» dans ce cas.
imoatama
5
et le% est un raccourci pour 1, $ (exécutez la commande suivante de la ligne 1 à la fin)
Lambart
3
Je suis intéressé par pourquoi %norm ddjne fonctionne pas si vous souhaitez supprimer des lignes impaires.
Cyker
10
:map ^o ddj^o
^o
Ici ^ représente CTRL. Macro récursive pour supprimer une ligne toutes les deux lignes. Choisissez bien votre première ligne et c'est fait.
Alors je préférerais !perl -ne 'print unless $. % 2':-)
Alex Brasetvik
Et, Alex, je préférerais définitivement ma solution à la vôtre, mais celle-ci mérite d'être prise en compte car c'est la seule solution sensée n'utilisant que vim lui-même ici.
Michael Krelin - hacker
La manière macro est tellement plus facile.
trusktr
+1 en raison de la flexibilité avec if (expression)laquelle fonctionne également pour chaque troisième ligne, etc.
Jens
5
Vous pouvez toujours exécuter une commande shell, ce qui signifie que vous pouvez utiliser n'importe quel langage de script que vous aimez:
:%!perl -nle 'print if $. % 2'
(ou utilisez "sauf" au lieu de "si", selon les lignes souhaitées)
Vous n'avez pas besoin de -lpasser à Perl ... aussi, je dirais que awkc'est un peu plus répandu que Perl, bien que ce ne soit pas vraiment beaucoup plus de nos jours, et que vous puissiez le faire plus court:, :%!awk NR\%2ou :%!awk 1-NR\%2pour les autres lignes.
Euh, pourquoi ne pas utiliser la NRvariable existante ?
éphémère
Droite. Parce que je l'ai oublié. ;-) Mais en fait, la variante "appropriée" sera encore plus longue avec NR. Et il n'y aurait pas deux beaux homologues.
Michael Krelin - hacker
:%!awk NR\%2ou :%!awk 1-NR\%2, comme je l'ai posté dans un autre commentaire. Ce n'est guère plus long.
éphémient
1
1-NRest plus long que c++. Oui, je sais que c'est un personnage. Comme je l'ai dit, la vraie raison est que je l'ai oublié. Quoi qu'il en soit, on dirait que les gens n'apprécient pas la beauté de awk ici.
Michael Krelin - hacker
Et NRest plus court que ++c:)
éphémère
3
Vous pouvez utiliser les propres capacités de recherche et de substitution de Vim comme ceci: Placez votre curseur sur la première ligne et tapez en mode normal:
:.,/fff/s/\n.*\(\n.*\)/\1/g
Le .,/fff/est la plage pour la substitution. Cela signifie "de cette ligne à la ligne qui correspond à l'expression régulière fff(dans ce cas, la dernière ligne).
s///est la commande de substitution. Il recherche une expression régulière et remplace chaque occurrence de celle-ci par une chaîne. Le gà la fin signifie répéter la substitution tant que l'expression régulière continue d'être trouvée.
L'expression régulière \n.*\(\n.*\)correspond à une nouvelle ligne, puis à une ligne entière ( .*correspond à n'importe quel nombre de caractères à l'exception d'une nouvelle ligne), puis à une autre nouvelle ligne et une autre ligne. Les parenthèses \(et \)provoquent l'enregistrement de l'expression à l'intérieur, afin que nous puissions l'utiliser plus tard en utilisant\1 .
\1 insère la nouvelle ligne groupée et la ligne qui suit, car nous ne voulons pas que la ligne suivante disparaisse aussi - nous voulons juste que le mécanisme de substitution passe à côté afin de ne pas la supprimer dans le prochain remplacement.
De cette façon, vous pouvez contrôler la plage dans laquelle vous souhaitez que la suppression ait lieu et vous n'avez pas besoin d'utiliser d'outil externe.
b = cb[:]copie temporairement toutes les lignes de la mémoire tampon actuelle dans b. b[::2]récupère chaque deuxième ligne du tampon et l'assigne à l'ensemble du tampon courant cb[:]. La copie vers best nécessaire car les objets tampons ne semblent pas prendre en charge la syntaxe de tranche étendue.
Ce n'est probablement pas la "manière vim", mais cela pourrait être plus facile à retenir si vous connaissez python.
Pour supprimer les lignes impaires (1,3,5, ..) -> :%s/\(.*\)\n\(.*\)\n/\2\r/g
Pour supprimer les lignes paires (2,4,6, ..) -> :%s/\(.*\)\n.*\n/\1\r/g
Recherchez du texte (forme la première ligne) suivi d'un caractère de nouvelle ligne et un peu plus de texte (forme la deuxième ligne) suivi d'un autre caractère de nouvelle ligne et remplacez ce qui précède par la première correspondance (ligne impaire) ou la deuxième correspondance (ligne paire) suivi d'un retour chariot.
:% !sed -e '2~2 d'
^^^^ pipe file through a shell command
^^^^^^ the command is sed, and -e describes an expression as parameter
^^^^^ starting with the second line, delete every second line
Réponses:
Vous pouvez utiliser une macro pour cela. Procédez comme suit.
gg
.qq
.dd
après.q
.10000@q
PS: Pour passer en mode commande, appuyez simplement sur Echap plusieurs fois.
la source
:g/^/+d
de l'utilisateur stackoverflow.com/users/254635/ib (ci-dessous) est un moyen plus élégant de résoudre ce problème.Un moyen élégant (et efficace) d'accomplir la tâche consiste à appeler la
:+delete
commande en supprimant la ligne qui suit la ligne actuelle, sur chaque ligne à l'aide de la:global
commande:la source
:1d|g/^/+d
supprime les lignes impaires.Nous pouvons utiliser
:normal
ou:norm
exécuter des commandes de mode normal données. La source.la source
%norm ddj
ne fonctionne pas si vous souhaitez supprimer des lignes impaires.Ici ^ représente CTRL. Macro récursive pour supprimer une ligne toutes les deux lignes. Choisissez bien votre première ligne et c'est fait.
la source
à partir de l' archive de messagerie vim :
(À taper sur une ligne de la ligne de commande vim, supprimera la ligne 1,3,5,7, ...)
la source
!perl -ne 'print unless $. % 2'
:-)if (expression)
laquelle fonctionne également pour chaque troisième ligne, etc.Vous pouvez toujours exécuter une commande shell, ce qui signifie que vous pouvez utiliser n'importe quel langage de script que vous aimez:
(ou utilisez "sauf" au lieu de "si", selon les lignes souhaitées)
la source
-l
passer à Perl ... aussi, je dirais queawk
c'est un peu plus répandu que Perl, bien que ce ne soit pas vraiment beaucoup plus de nos jours, et que vous puissiez le faire plus court:,:%!awk NR\%2
ou:%!awk 1-NR\%2
pour les autres lignes.alternativement
selon la moitié que vous souhaitez éliminer.
la source
NR
variable existante ?:%!awk NR\%2
ou:%!awk 1-NR\%2
, comme je l'ai posté dans un autre commentaire. Ce n'est guère plus long.1-NR
est plus long quec++
. Oui, je sais que c'est un personnage. Comme je l'ai dit, la vraie raison est que je l'ai oublié. Quoi qu'il en soit, on dirait que les gens n'apprécient pas la beauté de awk ici.NR
est plus court que++c
:)Vous pouvez utiliser les propres capacités de recherche et de substitution de Vim comme ceci: Placez votre curseur sur la première ligne et tapez en mode normal:
.,/fff/
est la plage pour la substitution. Cela signifie "de cette ligne à la ligne qui correspond à l'expression régulièrefff
(dans ce cas, la dernière ligne).s///
est la commande de substitution. Il recherche une expression régulière et remplace chaque occurrence de celle-ci par une chaîne. Leg
à la fin signifie répéter la substitution tant que l'expression régulière continue d'être trouvée.\n.*\(\n.*\)
correspond à une nouvelle ligne, puis à une ligne entière (.*
correspond à n'importe quel nombre de caractères à l'exception d'une nouvelle ligne), puis à une autre nouvelle ligne et une autre ligne. Les parenthèses\(
et\)
provoquent l'enregistrement de l'expression à l'intérieur, afin que nous puissions l'utiliser plus tard en utilisant\1
.\1
insère la nouvelle ligne groupée et la ligne qui suit, car nous ne voulons pas que la ligne suivante disparaisse aussi - nous voulons juste que le mécanisme de substitution passe à côté afin de ne pas la supprimer dans le prochain remplacement.De cette façon, vous pouvez contrôler la plage dans laquelle vous souhaitez que la suppression ait lieu et vous n'avez pas besoin d'utiliser d'outil externe.
la source
$
au lieu de/fff/
, pour la fin du fichier quel que soit le contenu du fichier.Comme autre approche, vous pouvez également utiliser python si votre vim le prend en charge.
b = cb[:]
copie temporairement toutes les lignes de la mémoire tampon actuelle dansb
.b[::2]
récupère chaque deuxième ligne du tampon et l'assigne à l'ensemble du tampon courantcb[:]
. La copie versb
est nécessaire car les objets tampons ne semblent pas prendre en charge la syntaxe de tranche étendue.Ce n'est probablement pas la "manière vim", mais cela pourrait être plus facile à retenir si vous connaissez python.
la source
Pour supprimer les lignes impaires (1,3,5, ..) ->
:%s/\(.*\)\n\(.*\)\n/\2\r/g
Pour supprimer les lignes paires (2,4,6, ..) ->
:%s/\(.*\)\n.*\n/\1\r/g
Recherchez du texte (forme la première ligne) suivi d'un caractère de nouvelle ligne et un peu plus de texte (forme la deuxième ligne) suivi d'un autre caractère de nouvelle ligne et remplacez ce qui précède par la première correspondance (ligne impaire) ou la deuxième correspondance (ligne paire) suivi d'un retour chariot.
la source
Appelez sed:
la source
Solution
vous pouvez essayer ceci dans vim
Éditer
J'essaierai d'être plus clair (deux parties)
première partie la plage de sélection (
:from,to
)deuxième partie l'action (
d
supprimer):1,$-1
)g
) delete (+1d
) ligne suivantevous pouvez essayer de passer à la première ligne de votre fichier et exécuter
:+1d
vous verrez la ligne suivante disparaîtreJe sais que c'est boueux, mais c'est vim et ça marche
la source