Comment compter les mots dans une partie d'un fichier, sans quitter vim?

10

J'ai un fichier plein de texte (disons Markdown ou LaTeX). Je voudrais compter le nombre de mots dans une partie de ce fichier.

Je sais que je peux faire :! wc -w %pour exécuter wc -w sur le tampon actuel. Et je sais que je peux extraire la section d'intérêt dans un registre nommé. Je suppose qu'il existe un moyen d'envoyer un registre nommé au système d'exploitation pour une utilisation dans une commande ou un canal, mais je n'ai pas pu en trouver un. Ou existe-t-il une meilleure façon de compter les mots dans un registre?

Mon cas d'utilisation est que je fais beaucoup d'écriture hors programmation (notes, thèses, etc.) dans vim, et je voudrais compter le nombre de mots que j'ai ajoutés à une section donnée du fichier au milieu d'une édition session.

Colin McFaul
la source

Réponses:

16

Vous pouvez utiliser gCTRL+g, ce qui vous donnera:

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

Vous pouvez également l'utiliser en mode visuel, si vous souhaitez obtenir le nombre de mots pour la sélection uniquement, ce qui est particulièrement utile combiné avec des objets texte tels que ip. (par exemple, vous pouvez utiliser vipg<C-g>pour obtenir le nombre de mots du paragraphe actuel).

Voir: :help word-countet :help text-objects.


L'option ci-dessus est probablement meilleure, mais vous pouvez également utiliser l' wcutilitaire pour compter le nombre de mots dans une section. Mis à part le :! wc -w %formulaire que vous utilisez, vous pouvez également utiliser :%!wc -w. Cela filtrera un mouvement vers un outil shell (dans ce cas %, la totalité du tampon), mais vous pouvez également utiliser d'autres plages (comme :1,5!wc -wpour les 5 premières lignes, !,+5!wc -wpour les 5 lignes actuelles et suivantes, etc.). Vous pouvez également sélectionner du texte en mode visuel et taper :!wc -wpour filtrer votre sélection.

Notez que cela remplacera le mouvement par la sortie de l'outil shell, mais vous pouvez l' uannuler.

Voir :help :range!, :help rangeet cette réponse où je donne plus d'exemples de plages.

Martin Tournoij
la source
J'avais trouvé quelque chose comme ça lors de la recherche, mais j'ai manqué que le premier g fasse partie de la commande de comptage, pas un spécificateur d'emplacement. Cette solution a du sens maintenant. Apparemment, je devrais également lire sur le mode visuel; Je ne l'utilise pas assez souvent.
Colin McFaul
1
Je ne savais pas que tu pouvais utiliser g<C-g>ça. Impressionnant!
EvergreenTree
3

Il y a deux façons d'accomplir cela, la voie pure vimscript et la wcvoie.

La pure voie Vim

Pour ce faire, vous pouvez utiliser la commande Rechercher et remplacer. Par exemple:

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

Au lieu de remplacer un motif donné par quelque chose, cela compte simplement les occurrences du motif. C'est à cause du ndrapeau. Pour compter les mots dans une section spécifique (dans ce cas, les lignes 5 à 15), vous pouvez faire quelque chose comme ceci:

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

Cela supprime la nécessité de copier le contenu d'une sélection dans un registre. Pour voir plus de possibilités pour ce qui peut être mis en place 5-15, lisez la rubrique d'aide pour cmdline-ranges. Si vous voulez le faire souvent, il est probablement bon de créer un mappage (ou une commande) pour cela. De plus, si vous l'avez hlsearchactivé, vous voudrez peut-être exécuter :nohlsearchensuite pour effacer la surbrillance.

Le wcchemin

La même chose peut être accomplie avec wc. De la même manière que vous pouvez utiliser cmdline-rangespour sélectionner la zone avec la :scommande, vous pouvez les utiliser avec des commandes externes. Par exemple:

:5,15!wc -w

Cela exécute les lignes 5 à 15 via la wccommande. L'inconvénient est qu'il remplace cette plage de lignes par la sortie de la commande. Vous pouvez annuler cette modification en appuyant sur u. Notez également que la solution vimscript peut ne pas fonctionner avec différentes langues, car \welle ne correspond pas à ce qui serait normalement des caractères de mot dans d'autres langues. wcpeut faire mieux que cela \w. En outre, voici une commande sophistiquée pour le faire plus rapidement:

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

Notez que cela encombre le aregistre.

Remarque

Il semble que cela puisse également être accompli en mode visuel avec la g<C-g>combinaison de touches. Voir la réponse de Carpetsmoker pour une explication à ce sujet.

Arbre à feuilles persistantes
la source
Ceux-ci ont besoin de ag avec le n pour les rendre globaux (sinon, ils ne correspondent qu'à un mot par ligne). Le second a également besoin d'un s au début.
Colin McFaul
1
Fixé, désolé.
EvergreenTree
1
Utiliser les \wsons comme une bonne idée au début, mais après l'avoir testée, j'ai trouvé un certain nombre de problèmes. Le plus important est qu'il ne correspondra pas aux caractères non ascii, donc un mot comme überest simplement ignoré (il y avait une question à ce sujet hier). De plus, un mot comme e-mailest compté comme 2 mots, car il -n'est pas en \w(l'utilisation de a -est quelque peu rare en anglais, mais très courante en néerlandais par exemple). Il peut y avoir d'autres personnages qui sont ignorés de cette façon, ce qui nous amène à mon dernier point: les conventions sur ce qui est considéré comme un "mot" peuvent différer ...
Martin Tournoij
... dans diverses langues, et des outils "appropriés" comme ceux qui wcpeuvent être récupérés sur les paramètres régionaux (je ne sais pas si GNU wcgère réellement cela en passant, les outils GNU ne sont pas bien connus pour leur excellent support Unicode).
Martin Tournoij
C'est intéressant. Je pourrais ajouter cela comme un plus à la wcsolution.
EvergreenTree
1

Pour les mots, utilisez:

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

. désigne la ligne actuelle.

J'ai également mis ce qui suit dans mon fichier .vimrc:

:cabbrev zzcc   s/./&/gn

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

Je peux taper:

:.,+6 zzcw

et zzcwva s'étendre às/\i\+/&/g

C'est zzcwjuste un nom étrange qui ne correspondra à rien (pour moi).

Un effet secondaire est que le fichier entier est sélectionné et mis en évidence.

Je voulais pouvoir taper des tweets sur plusieurs lignes dans un fichier, m'assurer qu'il n'y avait pas trop de caractères et coller le tweet sur Twitter.

elademanon
la source