Supprimer n lignes ignorer le script de 1 ligne

10

Je veux créer un script Vim de base qui supprime simplement n lignes, saute 1 ligne et se répète jusqu'à la fin du document. Je ne me soucie pas des correspondances spécifiques, je veux juste supprimer la ligne. Par exemple; Je veux donc répéter la commande 3ddjpour tout le document.

Text I want to keep.   
Text I want to delete.  
Text I want to delete.  
Text I want to delete.  
Text I want to keep.  
Text I want to delete.  
Text I want to delete.  
Text I want to delete.  
Text I want to keep.  
Text I want to delete.  
Text I want to delete.  
Text I want to delete.   

On dirait donc ...

Text I want to keep.  
Text I want to keep.  
Text I want to keep.  

Je vous remercie.

Max Copley
la source
Vous avez inclus la balise regular-expressionsur votre question, mais la question ne semble pas indiquer de raison de le faire avec des expressions régulières. Si vous recherchez réellement quelque chose qui utilise des expressions régulières, stackoverflow.com/questions/17735289/… peut être intéressant. Cette question concernait le Bloc-notes ++, mais la réponse n'utilise rien d'autre qu'une expression régulière pcre. (Avertissement: j'ai écrit cette réponse.)
Jasper
La prochaine fois que vous poserez une question, il n'est pas nécessaire d'écrire «Merci pour cela. Excellente solution! sur chaque réponse unique. Cela est même écrit lorsque vous essayez de créer un nouveau commentaire sur une réponse.
pipe
Pour ajouter à cela, la bonne façon de montrer votre appréciation ici est d'accepter la réponse qui vous a le mieux fonctionné et de voter pour toutes les réponses que vous jugez utiles ou utiles. Les gens préfèreraient de loin voir cela comme un "merci".
B Layer

Réponses:

19

Approche très simple:

  1. Accédez à la première ligne que vous souhaitez supprimer.
  2. Enregistrez une macro: qa3ddjq
  3. Répétez-le avec un nombre élevé: 1000 @ a

La troisième étape répétera la macro mille fois ou jusqu'à ce qu'une erreur se produise. Frapper la fin du fichier (donc pas de lignes à supprimer) produit une erreur et la répétition de la macro est annulée.

Tu vois :help recording.

Ralf
la source
2
C'est incroyable !!! Merci beaucoup, cela a fonctionné pour moi: D
Max Copley
1
explications: q(en mode commande, et dans vim ou d'autres versions alternatives récentes [neovim, etc.], mais pas dans le vi original) signifie "commencer l'enregistrement, et le mettre dans le tampon" lettre suivante "". donc: qasignifie "commencer l'enregistrement dans le tampon" a "". Ensuite, toutes les touches tapées après cela (jusqu'à la prochaine qen mode commande) sont enregistrées (vous pouvez même enregistrer: passer en mode édition, taper quelque chose, s'échapper en mode commande, etc.). Puis 12@arépéterait toutes les mesures ont été enregistrées dans le tampon « a » 12 fois.
Olivier Dulac
3
De plus, si vous ne voulez pas exécuter quelque chose comme 1000@qà la fin, vous pouvez créer une macro récursive:, qa3ddj@aq@abien que vous deviez d' qaqabord le faire pour vous assurer que le "adémarrage est vide.
James
17

La solution la plus simple pour moi serait:

:%norm j3dd

C'est:

  • %: pour chaque ligne
  • norm: exécutez les touches suivantes comme en mode normal
  • j3dd: descendre en ligne puis supprimer 3 lignes

Donc, à partir de la première ligne, descendez à la seconde et supprimez les 3 lignes suivantes. Le second Text I want to keep.est maintenant sur la deuxième ligne. Descendez d'une ligne, supprimez 3. Rincez et répétez.


Remarque: si vous ne souhaitez pas traiter l'intégralité du fichier, vous pouvez remplacer le %normpar exemple 5,$normpour traiter de la 5e ligne à la fin du fichier.

Marth
la source
4
Très belle alternative! Fonctionne dans vim (pas vi). Je n'avais jamais entendu parler de "norme" auparavant! (et je suis une sorte de vi [m] geek)
Olivier Dulac
6

Vous avez déjà d'excellentes solutions. En voici un autre:

:g/^/if line('.')%4!=1|:s/^/DELETE ME/|endif
:g/^DELETE ME/d

Tout d'abord, nous effectuons une action sur chaque ligne ( :gcorrespondant au ^(début de la ligne)) et pour chaque numéro de ligne effectuons le résultat de linenumber % 4. Si le résultat est différent de 1, nous ajoutons DELETE MEau début de la ligne, marquant les lignes à supprimer par la commande suivante.

La commande suivante est une commande regular ( :g), qui correspond à toutes les lignes commençant par DELETE MEet le fait.

Remarque, vous ne pouvez pas supprimer immédiatement la ligne à l'aide de la première :gcommande, car cela modifierait le calcul modulo résultant et en tant que tel, nous devons d'abord marquer les lignes et, dans un deuxième temps, le supprimer.

Christian Brabandt
la source
4

Je sais que c'est la vichaîne, mais pour moi, c'est un sedproblème.

sed -ne 'p;n;n;n' <file >newfile

Vous pouvez donc le transformer en une visolution:

:0
!Gsed -ne 'p;n;n;n'
dgc
la source
1
+1 pour une solution sed.
Christian Brabandt le
3

Une alternative (je suppose que nous commençons sur la ligne 1, et supprimons les lignes 2-4, 6-8 et ainsi de suite, selon un exemple de texte):

while line(".") < line("$")
    silent +1delete _ 3
endwhile

Si vous préférez le faire de manière interactive, vous pouvez utiliser le "registre de ligne de commande". Autrement dit, appuyez sur

:+1del 3<CR> puis 1000@:

Mat
la source
1

une alternative: vous souhaitez conserver toutes les lignes: 1, 4, etc. Vous pouvez utiliser:

awk '!((FNR-1)%3)'  file > newfile
      # awk: when a condition is given without action:
      #        prints the lines for which the condition returns 0.
      # FNR designates the line number in the current file.
      # a%3 : takes the modulus of a and 3. ( 0%3=0, 1%3=1, 2%3=2, 3%3=0, 4%3=1, etc.) 
      # This will be 0 for 3, 6, etc. 
      # But we want it to be 0 (true) for 1, 4, etc : so we substract 1 to NR

# to see that it keeps those lines:
seq 1 20 | awk '!((NR-1)%3)'
1
4
7
10
13
16
19

une autre alternative: si vous connaissez les lignes que vous souhaitez faire correspondre à un motif unique:

# for exemple each line you want contains "some pattern":
fgrep "some pattern" file > newfile
# (or regular grep if you want "some pattern" to be interpreted as a regexp)
Olivier Dulac
la source