Führen Sie einen Befehl in Vim über die Befehlszeile aus

72

Gibt es eine Möglichkeit, einen Vim-Befehl in einer Datei über die Befehlszeile auszuführen?

Ich weiß, dass das Gegenteil so ist:

:!python %

Aber was ist, wenn ich :retabeine Datei erstellen möchte, ohne sie in Vim zu öffnen? Zum Beispiel:

> vim myfile.c
:retab | wq

Dadurch wird myfile.c geöffnet, die Registerkarten durch Leerzeichen ersetzt und anschließend gespeichert und geschlossen. Ich möchte diese Sequenz irgendwie zu einem einzigen Befehl verketten.

Es wäre ungefähr so:

> vim myfile.c retab | wq
syvex
quelle

Antworten:

65

Das funktioniert:

gvim -c "set et|retab|wq" foo.txt

set et(= set expandtab) stellt sicher, dass die tabZeichen durch die richtige Anzahl von Leerzeichen ersetzt werden (andernfalls retabfunktioniert dies nicht).

Ich benutze es normalerweise nicht, aber vim -c ...es funktioniert auch

Die oben angegebene Lösung setzt voraus, dass der Standard-Tabulator von acht angemessen ist. Wenn beispielsweise ein Tabulator von vier vorgesehen ist, verwenden Sie die Befehlssequenz "set ts=4|set et|retab|wq".

Firstrock
quelle
Ich habe versucht, dies mit xargs( find -name \*.[ch] | xargs -n 1 vim -c "set et|retab|wq") auf mehreren Dateien auszuführen , aber das war sehr langsam. Bei jedem Aufruf beschwerte sich vim, dass die Eingabe nicht von einem Terminal stammte, und ich denke, es verzögert sich um ein oder zwei Sekunden, um das Lesen der Nachricht zu ermöglichen. Alternativ lässt eine for-Schleife stdin unberührt und ist so schnell : for f in $(find -name \*.[ch]); do vim -c "set et|retab|wq" $f; done. Dies ist jedoch nicht perfekt, z. B. brechen Dateinamen mit Leerzeichen oder zu viele Dateinamen dies ab (vim hat also möglicherweise die Option, diese Warnung zu unterdrücken).
Matthijs Kooijman
58

Sie haben mehrere Möglichkeiten:

  • -c "commands": spielt Ex-Befehle ab, wie Sie sie in die Befehlszeile eingegeben haben.
    In Ihrem Beispiel : vim myfile -c 'retab | wq'. Dies schlug Firstrock vor.

  • -S "vim source file": Quelle gegebenes vim-Skript
    (wie das Ausführen vim -c "source 'vim source file'"):

    Wenn Sie eine Datei haben, die Folgendes script.vimenthält:

    retab
    wq
    

    Dann können Sie verwenden vim myfile.c -s script.vim(die Erweiterung spielt keine Rolle)

  • -s "scriptin file": spielt den Inhalt einer Datei ab, da er Befehle für den normalen Modus enthält : Wenn Sie Folgendes script.txtenthalten:

    :retab
    ZZ
    

    Wenn das Zeilenende aus einem einzelnen ^MZeichen besteht (zum Beispiel haben Sie das Skript mit dem gespeichert :set fileformat=mac | w), können Sie Folgendes ausführen: vim myfile.c -S script.txt( ZZist eine weitere Möglichkeit, vim zu beenden und die aktuelle Datei zu speichern).
    Beachten Sie, dass Sie diese Skripte mit aufzeichnen können vim my_file -W script.txt, es jedoch einen Fehler gibt, wenn Sie zufällig gvim (die GUI) verwenden.

Benoit
quelle
1
Wenn Sie, wie ich, nur eine Handvoll Befehle ausführen möchten, können Sie einige Shells verwenden vim -S <(echo -e "VundleInstall \n q \n q").
Minix
2

Keine direkte Antwort auf Ihre Frage, aber wenn Sie Tabulatoren für eine Liste von Dateien durch Leerzeichen ersetzen (oder eine andere Regex-Suche / Ersetzung durchführen) möchten, können Sie einfach die direkte Suche / Ersetzung verwenden:

sed -i 's/\t/   /g' foo1.txt foo2.txt

oder

ls *.txt | xargs sed -i 's/\t/   /g'

(In diesem Beispiel ersetze ich jedes Tabulatorzeichen durch drei Leerzeichen.)


HINWEIS: Das -iFlag bedeutet, dass es an Ort und Stelle arbeitet.

Von der sedManpage:

   -i[SUFFIX], --in-place[=SUFFIX]

          edit files in place (makes backup if  extension
          supplied)
arr_sea
quelle
Sie haben Recht - man sollte das Mikroskop nicht wie einen Dosenöffner
benutzen
1
Nach meiner Erfahrung ist sed schmerzhaft langsam, wenn die Datei sehr groß ist (in der Größenordnung von 100 MB) und die Anzahl der Ersetzungen begrenzt ist. Die von @benoit vorgeschlagene Option 'vim -s <Skriptdatei>' funktioniert viel schneller - in der Größenordnung von Sekunden. In meinem Fall dauerte sed ungefähr 3 Minuten, während die vim-Skriptoption für eine 200 MB große Datei und ungefähr 100 Ersetzungen in ungefähr 25 Sekunden abgeschlossen war
Prashant