Wie zähle ich die Wörter in einem Teil einer Datei, ohne vim zu verlassen?

10

Ich habe eine Datei voller Text (z. B. Markdown oder LaTeX). Ich möchte die Anzahl der Wörter in einem Teil dieser Datei zählen.

Ich weiß, dass ich :! wc -w %wc -w auf dem aktuellen Puffer ausführen kann . Und ich weiß, dass ich den interessierenden Abschnitt in ein benanntes Register ziehen kann. Ich vermute, es gibt eine Möglichkeit, ein benanntes Register zur Verwendung in einem Befehl oder einer Pipe an das Betriebssystem zu senden, aber ich konnte keines finden. Oder gibt es eine bessere Möglichkeit, die Wörter in einem Register zu zählen?

Mein Anwendungsfall ist, dass ich viel nicht programmiertes Schreiben (Notizen, Abschlussarbeiten usw.) in vim mache und ich möchte zählen, wie viele Wörter ich während einer Bearbeitung zu einem bestimmten Abschnitt der Datei hinzugefügt habe Session.

Colin McFaul
quelle

Antworten:

16

Sie können verwenden gCTRL+g, die Ihnen geben wird:

Col 1 of 118-121; Line 1 of 5; Word 1 of 142; Byte 1 of 678

Sie können dies auch im visuellen Modus verwenden, wenn Sie die Wortanzahl nur für die Auswahl erhalten möchten, was besonders in Kombination mit Textobjekten wie z ip. (zB können Sie verwenden vipg<C-g>, um die Wortzahl des aktuellen Absatzes abzurufen).

Siehe: :help word-countund :help text-objects.


Die obige Option ist wahrscheinlich besser, aber Sie können auch das wcDienstprogramm verwenden, um die Anzahl der Wörter in einem Abschnitt zu zählen. Neben dem von :! wc -w %Ihnen verwendeten Formular können Sie auch verwenden :%!wc -w. Dadurch wird eine Bewegung auf ein Shell-Tool (in diesem Fall %den gesamten Puffer) gefiltert. Sie können jedoch auch andere Bereiche verwenden (z. B. :1,5!wc -wfür die ersten 5 Zeilen, !,+5!wc -wfür die aktuellen und die nächsten 5 Zeilen usw.). Sie können Text auch im visuellen Modus auswählen und eingeben :!wc -w, um Ihre Auswahl zu filtern.

Beachten Sie, dass dadurch die Bewegung durch die Ausgabe des Shell-Werkzeugs ersetzt wird. Sie können dies ujedoch rückgängig machen.

Siehe :help :range!, :help rangeund diese Antwort , wo ich weitere Beispiele für Bereiche geben.

Martin Tournoij
quelle
Ich hatte bei der Suche so etwas gefunden, aber übersehen, dass das erste g Teil des Zählbefehls ist und kein Standortspezifizierer. Diese Lösung macht jetzt Sinn. Ich sollte anscheinend auch den visuellen Modus nachlesen; Ich benutze es nicht oft genug.
Colin McFaul
1
Ich hatte keine Ahnung, dass Sie so verwenden könnten g<C-g>. Genial!
EvergreenTree
3

Es gibt zwei Möglichkeiten, wie dies erreicht werden kann, die reine Vimscript-Methode und die wcMethode.

Der reine Vim-Weg

Sie können dazu den Befehl suchen und ersetzen verwenden. Zum Beispiel:

:%s/\<\w\{-}\>//gn

Anstatt ein bestimmtes Muster durch etwas zu ersetzen, werden nur die Vorkommen des Musters gezählt. Dies liegt an der nFlagge. Um die Wörter in einem bestimmten Abschnitt (in diesem Fall in den Zeilen 5 bis 15) zu zählen, können Sie Folgendes tun:

:5,15s/\<\w\{-}\>//gn

Dadurch entfällt die Notwendigkeit, den Inhalt einer Auswahl in ein Register zu ziehen. 5-15Lesen Sie das Hilfethema für, um weitere Möglichkeiten für das zu sehen, was ersetzt werden kann cmdline-ranges. Wenn Sie dies häufig tun möchten, ist es wahrscheinlich gut, eine Zuordnung (oder einen Befehl) dafür zu erstellen. Wenn Sie hlsearchaktiviert haben, möchten Sie möglicherweise :nohlsearchanschließend ausgeführt werden, um die Hervorhebung zu löschen.

Der wcWeg

Das gleiche kann mit erreicht werden wc. Auf die gleiche Weise, wie Sie cmdline-rangesden Bereich mit dem :sBefehl auswählen können, können Sie sie mit externen Befehlen verwenden. Zum Beispiel:

:5,15!wc -w

Dies führt die Zeilen 5 bis 15 durch den wcBefehl. Der Nachteil dabei ist, dass dieser Zeilenbereich durch die Ausgabe des Befehls ersetzt wird. Sie können diese Änderung durch Drücken von rückgängig machen u. Beachten Sie auch, dass die Vimscript-Lösung möglicherweise nicht mit verschiedenen Sprachen \wfunktioniert , da sie nicht mit den Wortzeichen in anderen Sprachen übereinstimmt. wckann es besser machen als \w. Hier ist auch ein ausgefallener Befehl, um dies zu beschleunigen:

command -range=% -addr=lines WordCount execute '<count>!wc -w' | .y a | undo | echo @a

Beachten Sie, dass dies das aRegister blockiert .

Hinweis

Es scheint, dass dies auch im visuellen Modus mit der g<C-g>Tastenkombination erreicht werden kann. Eine Erklärung hierzu finden Sie in der Antwort von Carpetsmoker.

Immergrüner Baum
quelle
Diese benötigen ag zusammen mit dem n, um sie global zu machen (andernfalls stimmen sie nur mit einem Wort pro Zeile überein). Der zweite braucht auch ein s am Anfang.
Colin McFaul
1
Behoben, sorry dafür.
EvergreenTree
1
Die Verwendung \wklingt zunächst nach einer guten Idee, aber nach dem Testen habe ich eine Reihe von Problemen festgestellt. Das größte Problem ist, dass es nicht mit Nicht-ASCII-Zeichen übereinstimmt, sodass ein Wort wie übereinfach übersprungen wird ( gestern gab es eine Frage dazu ). Ein Wort wie e-mailwird auch als 2 Wörter gezählt, da -es nicht in ist \w(die Verwendung von a -ist im Englischen etwas ungewöhnlich, im Niederländischen jedoch sehr häufig). Es kann andere Zeichen geben, die auf diese Weise ignoriert werden, was uns zu meinem letzten Punkt bringt: Konventionen darüber, was als "Wort" angesehen wird, können abweichen ...
Martin Tournoij
... in verschiedenen Sprachen und "richtige" Tools wie wcdas Gebietsschema (ich weiß wcübrigens nicht, ob GNU tatsächlich damit umgeht, GNU-Tools sind nicht für ihre hervorragende Unicode-Unterstützung bekannt).
Martin Tournoij
Das ist interessant. Ich könnte das als Plus zur wcLösung hinzufügen .
EvergreenTree
1

Für Wörter verwenden Sie:

:.,+4 s/\i\+/&/gn

. bezeichnet die aktuelle Zeile.

Außerdem habe ich Folgendes in meine .vimrc-Datei eingefügt:

:cabbrev zzcc   s/./&/gn

:cabbrev zzcw   s/\i\+/&/g

Ich kann tippen:

:.,+6 zzcw

und der zzcwWille erweitert sich aufs/\i\+/&/g

Das zzcwist nur ein seltsamer Name, der (für mich) zu nichts passt.

Ein Nebeneffekt ist, dass die gesamte Datei ausgewählt und hervorgehoben wird.

Ich wollte in der Lage sein, mehrzeilige Tweets in eine Datei einzugeben, sicherzustellen, dass nicht zu viele Zeichen vorhanden sind, und den Tweet in Twitter einfügen.

Elademanon
quelle