Comment éditer des fichiers de manière non interactive (par exemple dans un pipeline)?

24

Je souhaite modifier les fichiers transmis en entrée de pipeline à l'aide de vim de manière non interactive ou modifier les fichiers sur place (similaire à sed).

Quelques exemples utilisant sed:

$ sed -i'.bak' s/foo/test/g file   # Edit file in-place.
$ cat file | sed s/foo/test/g      # Parse file in pipeline.

Cependant, je pourrais lire ici , que:

sedest un éditeur S tream ED , pas un éditeur de fichiers. Néanmoins, les gens du monde entier ont tendance à en abuser pour essayer d'éditer des fichiers. Il ne modifie pas les fichiers.

Deuxièmement, certaines options telles que l'édition sur place ( -i) sont portables.

Comment obtenir la même fonctionnalité dans vim?

kenorb
la source
Je pense que vous pouvez supprimer le second filede votre deuxième ligne de commande.
joeytwiddle
@joeytwiddle Terminé.
kenorb

Réponses:

33

Pour éditer un fichier de manière non interactive en utilisant ex( viest le mode visuel pour ex), vous pouvez utiliser des paramètres +{command}ou -c {command}qui vous permettent d'exécuter les commandes vi après la lecture du premier fichier.

L' exest un éditeur de ligne de commande standard (similaire à ed).

Il existe également vipe(un éditeur de canal de commande Vim) qui doit être utilisé moreutilset qui vous permet d'exécuter votre éditeur au milieu d'un pipeline Unix et de modifier les données qui sont transmises entre les programmes.

Exemples

L'entrée et la sortie standard simples à l'aide de canaux peuvent être obtenues par cette syntaxe shell:

$ ex -sc'%p|q!' <(echo Example)
$ echo Example | ex -sc'%p|q!' /dev/stdin

Voici un exemple simple pour imprimer le fichier après substitution:

$ ex /etc/hosts +%s/127/128/ge -sc'%p|q!'

Plus d'exemples pour éditer des fichiers sur place:

$ ex +'%s/127/128/g' -cswq file
$ ex -sc '%s/olddomain\.com/newdomain.com/g|x' file
$ printf '%s\n' 'g/olddomain\.com/s//newdomain.com/g' w q | ex -s file
$ ex -s "$file" <<< $'g/old/s//new/g\nw\nq'
$ ex -sc 'argdo %s/old/new/ge|x' ./**
$ find . -type f -exec ex -sc '%s/old/new/g|x' {} \;

Vous pouvez également utiliser -s {scriptin}pour que les commandes soient chargées à partir du fichier, par exemple:

$ printf "%s\n" '%s/foo/test/ge' 'wq' > cmds.vim
$ vim -s cmds.vim -es file

ou en utilisant la redirection d'E / S:

$ vim file < cmds.vim

Pour modifier un fichier et enregistrer les modifications dans un autre, consultez les exemples suivants:

$ ex +%s/127/128/g -sc'wq! new_file' /etc/hosts
$ cat /etc/hosts /etc/fstab | vim - -es '+:%s/foo/test/g' '+:wq! file3'

Des exemples plus pratiques.

Exemple réel en direct de la spécification RPM :

vim -E -s Makefile <<-EOF
   :%substitute/CFLAGS = -g$/CFLAGS =-fPIC -DPIC -g/
   :%substitute/CFLAGS =$/CFLAGS =-fPIC -DPIC/
   :%substitute/ADAFLAGS =$/ADAFLAGS =-fPIC -DPIC/
   :update
   :quit
EOF

Extraction de balises html :

ex -s +'bufdo!/<div.*id=.the_div_id/norm nvatdggdG"2p' +'bufdo!%p' -cqa! *.html

Suppression des balises XML :

ex -s +'%s/<[^>].\{-}>//ge' +%p +q! file.txt

Suppression de la balise de style de l'en-tête et impression de la sortie analysée:

curl -s http://example.com/ | ex -s +'/<style.*/norm nvatd' +%p -cq! /dev/stdin

Analyser du HTML avec plusieurs règles complexes:

ex -V1 $PAGE <<-EOF
  " Correcting missing protocol, see: https://github.com/wkhtmltopdf/wkhtmltopdf/issues/2359 "
  %s,'//,'http://,ge
  %s,"//,"http://,ge
  " Correcting relative paths, see: https://github.com/wkhtmltopdf/wkhtmltopdf/issues/2359 "
  %s,[^,]\zs'/\ze[^>],'http://www.example.com/,ge
  %s,[^,]\zs"/\ze[^>],"http://www.example.com/,ge
  " Remove the margin on the left of the main block. "
  %s/id="doc_container"/id="doc_container" style="min-width:0px;margin-left : 0px;"/g
  %s/<div class="outer_page/<div style="margin: 0px;" class="outer_page/g
  " Remove useless html elements. "
  /<div.*id="global_header"/norm nvatd
  wq " Update changes and quit.
EOF

Encore plus d'exemples:


Voir également:


kenorb
la source
5
Ceci est un UUOC ; utilisez simplement à la vim '+:0,$s/foo/test/g' '+:wq! file2' file1place.
Poignée de porte
2
Notez que au moins certains de ces exemples ne sont pas conformes POSIX, par exemple, bufdo. Même si Vim est ce qui est installé pratiquement partout, il vaut la peine de savoir que vous pouvez modifier les fichiers de script en utilisant uniquement les fonctionnalités compatibles POSIX deex .
Wildcard
Cette question et réponse est ce qui m'a inspiré pour la première fois à étudier exet à vraiment l'apprendre. Merci. Une lecture supplémentaire sur ce sujet (divulgation complète: j'ai écrit ces;) est la suivante: inverser toutes les quatre lignes avecex et utiliser l' -coption . Vous pouvez les ajouter à votre liste de liens en bas, si vous le souhaitez. :)
Wildcard