Ich suche nach dem besten Weg, um (mit Bestätigung) alle Projektdateien in Vim zu suchen und zu ersetzen. Mit "Projektdateien" meine ich Dateien im aktuellen Verzeichnis, von denen einige nicht geöffnet sein müssen.
Eine Möglichkeit, dies zu tun, könnte darin bestehen, einfach alle Dateien im aktuellen Verzeichnis zu öffnen:
:args ./**
und dann suchen und ersetzen Sie alle geöffneten Dateien:
:argdo %s/Search/Replace/gce
Wenn ich dies tue, springt die Speichernutzung von Vim jedoch von ein paar Dutzend MB auf über 2 GB, was für mich nicht funktioniert.
Ich habe auch das EasyGrep- Plugin installiert, aber es funktioniert fast nie - entweder findet es nicht alle Vorkommen oder es hängt nur, bis ich drücke CtrlC. Bisher mein bevorzugter Weg , um diese Aufgabe zu erfüllen , es zu ack-grep für den Suchbegriff ein , es ist quickfix Fenster einer beliebige Datei öffnen verwenden, die den Begriff und wurde nicht vor dem Öffnen, und schließlich :bufdo %s/Search/Replace/gce
.
Ich suche entweder nach einem guten, funktionierenden Plugin, das dafür verwendet werden kann, oder nach einem Befehl / einer Folge von Befehlen, die einfacher wären als der, den ich jetzt verwende.
Antworten:
Greplace funktioniert gut für mich.
Es gibt auch eine Pathogen-fähige Version auf Github.
quelle
:Gsearch
und:Gbuffersearch
existiere, aber wenn ich tippe,:Greplace
bekomme ichNot an editor command: Greplace
.:Gsearch [<grep-option(s)>] [[<pattern>] [<filename(s)>]]
So können Sie eine rekursive Suche durchführen, indem Sie beispielsweise:Gsearch -r pattern dir/
Die andere große Option hier ist einfach, vim nicht zu verwenden:
oder wenn Sie eine Möglichkeit haben, eine Liste von Dateien zu erstellen, vielleicht so etwas:
und so weiter!
quelle
sed
reguläre Ausdrücke, bei denen es sich im Wesentlichen um reguläre POSIX.2-Grundausdrücke handelt, aber nicht genau (dies steht auf der Manpage) - sie lassen\n
Zeilenumbrüche und einige ähnliche Dinge übereinstimmen. Sie sind daher so ziemlich die gleichen wiegrep
reguläre Ausdrücke.find . -type f | LANG=C xargs sed -i '' 's/SEARCH/REPLACE/g'
BEARBEITEN: Verwenden Sie den
cfdo
Befehl anstattcdo
, um die Anzahl der Befehle, die ausgeführt werden, um dies zu erreichen, erheblich zu reduzieren (dacdo
Befehle für jedes Element ausgeführt werden, währendcfdo
Befehle für jede Datei ausgeführt werden).Dank des kürzlich hinzugefügten
cdo
Befehls können Sie dies jetzt in zwei einfachen Befehlen mit dem vongrep
Ihnen installierten Tool ausführen . Keine zusätzlichen Plugins erforderlich!:(
cdo
Führt den gegebenen Befehl zu jedem Begriff in der Quickfix ist , dergrep
Befehl bevölkert.)(Entfernen Sie das
c
am Ende des 2. Befehls, wenn Sie jeden Suchbegriff ersetzen möchten, ohne dies jedes Mal zu bestätigen.)quelle
:cdo update
, um die Änderungen in allen Dateien zu speichern.c
am Ende des zweiten Befehls entfernen (einfach verwendeng
), um ihn suchen und ersetzen zu lassen, ohne um Bestätigung zu bittenupdate
musste ich:cdo %s/<search term>/<replace term>/g | update
Ich habe mich entschieden, ack und Perl zu verwenden, um dieses Problem zu lösen, um die leistungsstärkeren regulären Perl-Vollausdrücke anstelle der GNU-Teilmenge zu nutzen.
Erläuterung
ack
ack ist ein wunderbares Kommandozeilen - Tool , das eine Mischung aus ist
grep
,find
und volle Perl reguläre Ausdrücke (nicht nur die GNU Teilmenge). Es ist in reinem Perl geschrieben, schnell, hat Syntaxhervorhebung, funktioniert unter Windows und ist für Programmierer freundlicher als die herkömmlichen Befehlszeilentools. Installiere es auf Ubuntu mitsudo apt-get install ack-grep
.xargs
Xargs ist ein altes Unix-Befehlszeilentool. Es liest Elemente aus der Standardeingabe und führt den angegebenen Befehl aus, gefolgt von den für die Standardeingabe gelesenen Elementen. Grundsätzlich wird die Liste der von ack generierten Dateien an das Ende des
perl -pi -E 's/pattern/replacemnt/g'
Befehls angehängt .Perl-pi
Perl ist eine Programmiersprache. Die Option -p bewirkt, dass Perl eine Schleife um Ihr Programm erstellt, die über Dateinamenargumente iteriert. Die Option -i bewirkt, dass Perl die Datei an Ort und Stelle bearbeitet. Sie können dies ändern, um Sicherungen zu erstellen. Die Option -E bewirkt, dass Perl die eine als Programm angegebene Codezeile ausführt. In unserem Fall ist das Programm nur eine Perl-Regex-Substitution. Weitere Informationen zu Perl-Befehlszeilenoptionen
perldoc perlrun
. Weitere Informationen zu Perl finden Sie unter http://www.perl.org/ .quelle
vielleicht mach das:
Erläuterung:
:noautocmd vim /Search/ **/*
⇒ Suchmuster (vim
ist eine Abkürzung fürvimgrep
) in allen Dateien in allen Unterverzeichnissen des cwd, ohne autocmds (:noautocmd
) aus Gründen der Geschwindigkeit auszulösen .:set hidden
⇒ Zulassen, dass geänderte Puffer nicht in einem Fenster angezeigt werden (möglicherweise in Ihrem vimrc):cfirst
⇒ zum ersten Suchergebnis springenqa
⇒ Starten Sie die Aufnahme eines Makros in Register a:%s//Replace/gce
⇒ Ersetzen Sie alle Vorkommen des letzten Suchmusters (noch/Search/
zu diesem Zeitpunkt) durchReplace
:g
Flagge)c
Flag)e
Flag):cnf
⇒ Zur nächsten Datei in der vomvim
Befehl erstellten Liste springenq
⇒ Aufnahme des Makros beenden1000@a
⇒ Spielmakro 1000-mal im Register gespeichert:wa
⇒ Speichern Sie alle geänderten Puffer* EDIT * Vim 8 Weg:
Ab Vim 8 gibt es eine bessere Möglichkeit, da
:cfdo
alle Dateien in der Quickfix-Liste wiederholt werden:quelle
vim
es mich für viele Dinge überzeugt hat, denke ich, dass ich dabei bei PowerGrep bleiben werde.Füllen Sie
:args
aus einem Shell-BefehlEs ist möglich (unter einigen Betriebssystemen 1 ), die Dateien
:args
über einen Shell-Befehl bereitzustellen .Wenn Sie beispielsweise ack 2 installiert haben,
wird ack bitten, eine Liste von Dateien zurückzugeben, die 'pattern' enthalten, und diese in die Argumentliste aufzunehmen.
Oder mit einfachem altem Grep, denke ich, wäre es:
Sie können dann einfach
:argdo
wie vom OP beschrieben verwenden:Füllen Sie
:args
aus der Quickfix-ListeLesen Sie auch die Antwort von nelstrom auf eine verwandte Frage, die einen einfachen benutzerdefinierten Befehl beschreibt, der die Arglist aus der aktuellen Quickfix-Liste auffüllt. Dies funktioniert hervorragend mit vielen Befehlen und Plugins, deren Ausgabe in der Quickfix-Liste (
:vimgrep
,:Ack
3 ,:Ggrep
4 ) landet .Die Sequenz zum Durchführen einer projektweiten Suche könnte dann folgendermaßen ausgeführt werden:
Wo
:Qargs
ist der Aufruf des benutzerdefinierten Befehls, der die Arglist aus der Quickfix-Liste auffüllt?In der folgenden Diskussion finden Sie auch Links zu einfachen Plugins, die diesen Workflow auf 2 oder 3 Befehle reduzieren.
Links
quelle
Eine weitere Option im Jahr 2016, far.vim Plugin:
quelle
Wenn es Ihnen nichts ausmacht, externe Abhängigkeiten einzuführen, habe ich ein Plugin ctrlsf.vim (abhängig von ack oder ag ) erstellt, um die Aufgabe zu erledigen.
Es kann das Suchergebnis von ack / ag formatieren und anzeigen und Ihre Änderungen im Ergebnispuffer mit den tatsächlichen Dateien auf der Festplatte synchronisieren.
Vielleicht erklärt die folgende Demo mehr
quelle
Schritt 1 füllt die Quickfix-Liste mit den gewünschten Elementen. In diesem Fall wird es mit Suchbegriffen weitergegeben, über die Sie Änderungen vornehmen möchten
grep
.cfdo
führt den folgenden Befehl für jede Datei in der Quickfix-Liste aus. Geben Sie:help cfdo
für Details ein.s/<search term>/<replace term>/g
ersetzt jeden Begriff./g
bedeutet, jedes Vorkommen in der Datei zu ersetzen.| update
speichert die Datei nach jedem Austausch.Ich habe dies basierend auf dieser Antwort und ihren Kommentaren zusammengesetzt, aber ich hatte das Gefühl, dass es eine eigene Antwort verdient, da alles an einem Ort ist.
quelle
2. :cfdo %s/<search term>/<replace term>/g | update
Ohne das%
wird nur das erste Auftreten des Musters ersetzt.%s
mit normalem vim funktioniert.Grundsätzlich wollte ich das Ersetzen in einem einzigen Befehl und vor allem in vim selbst
Basierend auf der Antwort von @Jefromi habe ich eine Tastenkombination erstellt, die ich in meiner .vimrc-Datei wie folgt festgelegt hatte
jetzt von der vim, auf einen Strich von führer + r bekomme ich den Befehl in vim geladen, den ich wie unten bearbeite,
Daher ersetze ich mit einem einzigen Befehl und vor allem innerhalb von vim
quelle