web-dev-qa-db-fra.com

Comment exécuter une série de commandes vim à partir de l'invite de commande

J'ai quatre fichiers texte A.txt, B.txt, C.txt et D.txt Je dois effectuer une série de modifications vim dans tous ces fichiers. Actuellement, comment je fais est d'ouvrir chaque fichier et d'exécuter les mêmes commandes vim une par une.

Est-il possible de créer un fichier script que je peux exécuter à partir de l'invite de commande, signifie sans ouvrir le fichier réel pour l'édition vim.

par exemple, si je dois exécuter les commandes vim ci-dessous après avoir ouvert le fichier A.txt dans l'éditeur vim:

:g/^\s*$/d
:%s/^/[/
:%s/\(.*\)\(\s\+\)\(.*\)/\3\2\1
:%s/$/]/
:%s/design/test/

Est-il possible de créer un fichier script et de mettre toutes ces commandes, y compris gvim A.txt (première commande du fichier). et éditez exécutez le fichier de script à partir de l'invite de commandes.

Si cela est possible, veuillez me faire savoir comment le faire, veuillez également me faire savoir comment cela peut être fait avec un seul fichier à la fois et plusieurs fichiers à la fois?

38
imbichie
vim -c <command> Execute <command> after loading the first file

Fait ce que vous décrivez, mais vous devrez le faire un fichier à la fois.

Donc, dans un shell Windows ...

for %a in (A,B,C,D) do vim -c ":g/^\s*$/d" -c "<another command>" %a.txt

Les obus POSIX sont similaires, mais je n'ai pas de machine devant moi pour le moment.

J'imagine que vous pourriez charger tous les fichiers en même temps et le faire, mais cela nécessiterait de répéter les commandes sur la ligne de commande vim pour chaque fichier, similaire à

vim -c "<command>" -c "<command>" -c ":n" (repeat the previous -c commands for each file.)  <filenames go here>

EDIT: 08 juin 2014: Juste un FYI, je l'ai découvert il y a quelques minutes.

vim a la commande bufdo pour faire des choses sur chaque tampon (fichier) chargé dans l'éditeur. Regardez les documents de la commande bufdo. Dans vim, :help bufdo

29
JimR

Avec toutes les commandes que vous souhaitez exécuter sur chaque fichier enregistré dans un script, par exemple "script.vim", vous pouvez exécuter ce script sur un fichier comme celui-ci (comme d'autres l'ont mentionné):

vim -c "source script.vim" A.txt

En poursuivant cette étape, vous pouvez enregistrer votre fichier à la fin du script, soit en mettant un :w commande à l'intérieur du script lui-même, ou en le passant depuis la ligne de commande:

vim -c "source script.vim | w" A.txt

Maintenant, vous pouvez exécuter n'importe quelle commande dans Vim sur plusieurs fichiers, en utilisant la commande argdo. Votre commande se transforme donc en:

vim -c "argdo source script.vim | w" A.txt B.txt C.txt D.txt

Enfin, si vous souhaitez quitter Vim après avoir exécuté votre script sur chaque fichier, ajoutez simplement une autre commande pour quitter:

vim -c "argdo source script.vim | w" -c "qa" A.txt B.txt C.txt D.txt
18
Ben

La quantité de -c les commandes directement passées à Vim sur la ligne de commande sont limitées à 10, ce qui n'est pas très lisible. Alternativement, vous pouvez placer les commandes dans un script séparé et les transmettre à Vim. Voici comment:

Mode batch silencieux

Pour un traitement de texte très simple (c'est-à-dire en utilisant Vim comme un 'sed' ou 'awk' amélioré, peut-être simplement en profitant des expressions régulières améliorées dans un :substitute commande), utilisez Ex-mode.

REM Windows
call vim -N -u NONE -n -es -S "commands.ex" "filespec"

Remarque: mode batch silencieux (:help -s-ex) gâche la console Windows, vous devrez donc peut-être faire un cls pour nettoyer après l'exécution de Vim.

# Unix
vim -T dumb --noplugin -n -es -S "commands.ex" "filespec"

Attention: Vim suspendra l'attente de l'entrée si le "commands.ex" le fichier n'existe pas; mieux vérifier au préalable son existence! Alternativement, Vim peut lire les commandes depuis stdin. Vous pouvez également remplir un nouveau tampon avec du texte lu depuis stdin et lire les commandes de stderr si vous utilisez le - argument.

Automatisation complète

Pour un traitement plus avancé impliquant plusieurs fenêtres et une véritable automatisation de Vim (où vous pourriez interagir avec l'utilisateur ou laisser Vim fonctionner pour laisser l'utilisateur prendre le relais), utilisez:

vim -N -u NONE -n -c "set nomore" -S "commands.vim" "filespec"

Voici un résumé des arguments utilisés:

-T dumb           Avoids errors in case the terminal detection goes wrong.
-N -u NONE        Do not load vimrc and plugins, alternatively:
--noplugin        Do not load plugins.
-n                No swapfile.
-es               Ex mode + silent batch mode -s-ex
                Attention: Must be given in that order!
-S ...            Source script.
-c 'set nomore'   Suppress the more-Prompt when the screen is filled
                with messages or output to avoid blocking.
18
Ingo Karkat

Essayez la syntaxe suivante:

ex foo.txt <<-EOF
  g/^\s*$/d
  %s/^/[/
  %s/\(.*\)\(\s\+\)\(.*\)/\3\2\1
  %s/$/]/
  %s/design/test/
  wq " Update changes and quit.
EOF

La commande ex est équivalente à vim -E. Ajouter -V1 pour une sortie détaillée.

La syntaxe alternative à une ligne est par exemple:

ex +"g/^\s*$/d" +"%s/^/[/" +"%s/design/test/" -cwq foo.txt

Pour charger des commandes à partir du fichier, utilisez -s cmds.vim.

Vous pouvez également utiliser Shebang for Vim pour analyser le fichier à partir de l'argument .

Pour plus d'exemples, voir:

6
kenorb

JimR et Ingo ont fourni d'excellentes réponses à votre cas d'utilisation.

Juste pour ajouter une autre façon de le faire, cependant, vous pouvez utiliser mon plugin vimrunner pour scripter l'interaction dans Ruby: https://github.com/AndrewRadev/vimrunner .

Exemple:

vim = Vimrunner.start

vim.edit "file.txt"
vim.insert "Hello"
vim.write

vim.kill

Cela peut être utile pour des interactions plus complexes, car vous obtenez toute la puissance d'un langage de programmation.

2
Andrew Radev