Jak policzyć słowa w części pliku, nie pozostawiając vima?

10

Mam plik pełen tekstu (np. Markdown lub LaTeX). Chciałbym policzyć liczbę słów w części tego pliku.

Wiem, że mogę zrobić, :! wc -w %aby uruchomić wc -w na bieżącym buforze. I wiem, że mogę wciągnąć interesującą sekcję do rejestru nazwanego. Zgaduję, że istnieje sposób wysłania nazwanego rejestru do systemu operacyjnego w celu użycia go w poleceniu lub potoku, ale nie udało mi się go znaleźć. Czy jest lepszy sposób na policzenie słów w rejestrze?

Mój przypadek użycia polega na tym, że dużo piszę w języku innym niż programowanie (notatki, praca dyplomowa itp.) I chciałbym policzyć, ile słów dodałem do danej sekcji pliku w trakcie edycji sesja.

Colin McFaul
źródło

Odpowiedzi:

16

Możesz użyć gCTRL+g, co da ci:

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

Możesz również użyć tego z trybu wizualnego, jeśli chcesz uzyskać liczbę słów dla samego wyboru, co jest szczególnie przydatne w połączeniu z obiektami tekstowymi, takimi jak ip. (np. możesz użyć, vipg<C-g>aby uzyskać liczbę słów w bieżącym akapicie).

Zobacz: :help word-counti :help text-objects.


Powyższa opcja jest prawdopodobnie lepsza, ale możesz również użyć wcnarzędzia do policzenia liczby słów w sekcji. Oprócz :! wc -w %formularza, którego używasz, możesz także użyć :%!wc -w. Spowoduje to odfiltrowanie ruchu do narzędzia powłoki (w tym przypadku %całego bufora), ale możesz również użyć innych zakresów (takich jak :1,5!wc -wdla pierwszych 5 linii, !,+5!wc -wdla bieżącej i następnych 5 linii itp.). Możesz także zaznaczyć tekst w trybie wizualnym i wpisać, :!wc -waby przefiltrować zaznaczenie.

Zauważ, że spowoduje to zastąpienie ruchu wyjściem narzędzia powłoki, ale możesz uto cofnąć.

Zobaczyć :help :range!, :help rangei ta odpowiedź gdzie daję więcej przykładów zakresów.

Martin Tournoij
źródło
Podczas wyszukiwania znalazłem coś takiego, ale nie zauważyłem, że pierwsze g jest częścią polecenia liczenia, a nie specyfikatorem lokalizacji. To rozwiązanie ma teraz sens. Najwyraźniej powinienem także przeczytać o trybie wizualnym; Nie używam go wystarczająco często.
Colin McFaul
1
Nie miałem pojęcia, że ​​możesz tego użyć g<C-g>. Niesamowite!
EvergreenTree
3

Można to osiągnąć na dwa sposoby: sposób na czysty skrypt i wcsposób.

Czysty sposób vim

Aby to zrobić, możesz użyć polecenia Wyszukaj i zamień. Na przykład:

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

To, co robi, to zamiast zastąpienia danego wzoru czymś, po prostu zlicza wystąpienia tego wzoru. Wynika to z nflagi. Aby policzyć słowa w określonej sekcji (w tym przypadku wiersze od 5 do 15), możesz zrobić coś takiego:

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

Eliminuje to potrzebę szarpania zawartości zaznaczenia w rejestrze. Aby zobaczyć więcej możliwości wprowadzenia tego, co można zastąpić 5-15, przeczytaj temat pomocy dla cmdline-ranges. Jeśli chcesz to robić często, prawdopodobnie dobrze jest utworzyć dla niego mapowanie (lub polecenie). Ponadto, jeśli hlsearchwłączyłeś, możesz chcieć uruchomić :nohlsearchpóźniej, aby usunąć zaznaczenie.

wcsposób

To samo można osiągnąć wc. W ten sam sposób, w jaki możesz użyć cmdline-rangesdo wybrania obszaru za pomocą :spolecenia, możesz używać ich z poleceniami zewnętrznymi. Na przykład:

:5,15!wc -w

To uruchamia wiersze od 5 do 15 za pomocą wcpolecenia. Wadą tego jest to, że zastępuje ten zakres wierszy wynikiem polecenia. Możesz cofnąć tę zmianę, naciskając u. Zauważ również, że rozwiązanie vimscript może nie działać z różnymi językami, ponieważ \wnie pasuje do znaków, które normalnie byłyby znakami słów w innych językach. wcmoże w tym lepiej \w. Oto też fantazyjne polecenie, aby przyspieszyć to:

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

Zauważ, że to kasuje arejestr.

Uwaga

Wydaje się, że można to również osiągnąć w trybie wizualnym za pomocą g<C-g>kombinacji klawiszy. Wyjaśnij to w odpowiedzi Carpetsmokera.

Wiecznie zielone drzewo
źródło
Potrzebują one razem z n, aby były globalne (w przeciwnym razie pasują tylko do jednego słowa w wierszu). Drugi też potrzebuje na początku.
Colin McFaul
1
Naprawiono, przepraszam za to.
EvergreenTree
1
\wPoczątkowo używanie brzmi jak niezły pomysł, ale po przetestowaniu go znalazłem wiele problemów. Najważniejsze jest to, że nie będzie pasowało do znaków innych niż ascii, więc słowo podobne überjest po prostu pomijane ( wczoraj było pytanie o to ). Również słowo podobne e-mailjest liczone jako 2 słowa, ponieważ -nie występuje w nim \w(użycie a -jest dość rzadkie w języku angielskim, ale bardzo powszechne na przykład w języku niderlandzkim). Mogą istnieć inne postacie, które są ignorowane w ten sposób, co prowadzi nas do ostatniego punktu: konwencje dotyczące tego, co uważa się za „słowo” mogą się różnić ...
Martin Tournoij
... w różnych językach i „odpowiednie” narzędzia, takie jak wcmogą przechwytywać ustawienia regionalne (nie wiem, czy GNU wctak na marginesie sobie z tym radzi, narzędzia GNU nie są dobrze znane z doskonałej obsługi Unicode).
Martin Tournoij
To jest interesujące. Mogę dodać to jako plus do wcrozwiązania.
EvergreenTree
1

Do słów użyj:

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

. oznacza bieżącą linię.

W moim pliku .vimrc umieściłem również:

:cabbrev zzcc   s/./&/gn

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

Mogę pisać:

:.,+6 zzcw

i zzcwrozszerzy się dos/\i\+/&/g

To zzcwpo prostu dziwne imię, które nic nie pasuje (dla mnie).

Efektem ubocznym jest zaznaczenie i wyróżnienie całego pliku.

Chciałem móc wpisywać tweety wieloliniowe w pliku, upewnić się, że nie ma zbyt wielu znaków i wkleić tweet na Twitterze.

elademanon
źródło