¿Cómo cuento las palabras en una parte de un archivo, sin dejar vim?

10

Tengo un archivo lleno de texto (por ejemplo, Markdown o LaTeX). Me gustaría contar la cantidad de palabras en una parte de este archivo.

Sé que puedo hacer :! wc -w %para ejecutar wc -w en el búfer actual. Y sé que puedo arrastrar la sección de interés a un registro con nombre. Supongo que hay una manera de enviar un registro con nombre al sistema operativo para su uso en un comando o canalización, pero no he podido encontrar uno. ¿O hay una mejor manera de contar las palabras en un registro?

Mi caso de uso es que escribo mucho sin programación (notas, tesis, etc.) en vim, y me gustaría contar cuántas palabras he agregado a una sección determinada del archivo en medio de una edición sesión.

Colin McFaul
fuente

Respuestas:

16

Puedes usar gCTRL+g, lo que te dará:

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

También puede usar esto desde el modo visual, si desea obtener el recuento de palabras solo para la selección, lo que es especialmente útil combinado con objetos de texto como ip. (por ejemplo, puede usar vipg<C-g>para obtener el recuento de palabras del párrafo actual).

Ver: :help word-county :help text-objects.


La opción anterior es probablemente mejor, pero también puede usar la wcutilidad para contar la cantidad de palabras en una sección. Además del :! wc -w %formulario que usa, también puede usarlo :%!wc -w. Esto filtrará un movimiento a una herramienta de shell (en este caso %, todo el búfer), pero también puede usar otros rangos (como :1,5!wc -wpara las primeras 5 líneas, !,+5!wc -wpara las 5 líneas actuales y siguientes, etc.). También puede seleccionar texto en modo visual y escribir :!wc -wpara filtrar su selección.

Tenga en cuenta que esto reemplazará el movimiento con la salida de la herramienta de shell, pero puede udeshacer esto.

Vea :help :range!, :help rangey esta respuesta donde doy más ejemplos de rangos.

Martin Tournoij
fuente
Había encontrado algo como esto mientras buscaba, pero me perdí que la primera g es parte del comando de conteo, no un especificador de ubicación. Esta solución tiene sentido ahora. Aparentemente, también debería leer en modo Visual; No lo uso con la suficiente frecuencia.
Colin McFaul
1
No tenía idea de que pudieras usarlo de g<C-g>esa manera. ¡Increíble!
EvergreenTree
3

Hay dos maneras en que esto se puede lograr, la forma pura de vimscript y la wcforma.

El camino puro vim

Puede usar el comando de búsqueda y reemplazo para hacer esto. Por ejemplo:

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

Lo que esto hace es en lugar de reemplazar un patrón dado con algo, solo cuenta las ocurrencias del patrón. Esto se debe a la nbandera. Para contar las palabras en una sección específica (en este caso, líneas 5 a 15), puede hacer algo como esto:

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

Esto elimina la necesidad de tirar del contenido de una selección a un registro. Para ver más posibilidades de lo que se puede poner en su lugar 5-15, lea el tema de ayuda cmdline-ranges. Si desea hacer esto a menudo, probablemente sea bueno crear una asignación (o comando) para ello. Además, si ha hlsearchhabilitado, es posible que desee ejecutar :nohlsearchdespués para borrar el resaltado.

El wccamino

Lo mismo se puede lograr con wc. De la misma manera que puede usar cmdline-rangespara seleccionar el área con el :scomando, puede usarlos con comandos externos. Por ejemplo:

:5,15!wc -w

Esto ejecuta las líneas 5 a 15 a través del wccomando. La desventaja de esto es que reemplaza ese rango de líneas con la salida del comando. Puede deshacer este cambio presionando u. También tenga en cuenta que la solución vimscript puede no funcionar con diferentes idiomas, ya \wque no coincide con lo que normalmente serían caracteres de palabras en otros idiomas. wcpuede hacerlo mejor en esto que \w. Además, aquí hay un comando sofisticado para hacerlo más rápido:

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

Tenga en cuenta que esto cambia el aregistro.

Nota

Parece que esto también se puede lograr en modo visual con la g<C-g>combinación de teclas. Vea la respuesta de Carpetsmoker para una explicación de esto.

Árbol de hoja perenne
fuente
Estos necesitan ag junto con la n para que sean globales (de lo contrario, solo coinciden con una palabra por línea). El segundo también necesita una s al principio.
Colin McFaul
1
Solucionado, perdón por eso.
EvergreenTree
1
Usar \wsonidos parece una buena idea al principio, pero después de probarlo encontré una serie de problemas. Lo más importante es que no coincidirá con caracteres que no sean ascii, por lo que una palabra como übersimplemente se omite ( ayer hubo una pregunta sobre esto ). Además, una palabra como e-mailse cuenta como 2 palabras, ya -que no está en \w(usar a -es algo poco común en inglés, pero muy común en holandés, por ejemplo). Puede haber otros personajes que se ignoran de esta manera, lo que nos lleva a mi último punto: las convenciones sobre lo que se considera una "palabra" pueden diferir ...
Martin Tournoij
... en varios idiomas, y las herramientas "adecuadas" como wcpueden aparecer en la configuración regional (no sé si GNU wcrealmente se ocupa de esto por cierto, las herramientas GNU no son bien conocidas por su excelente soporte Unicode).
Martin Tournoij
Eso es interesante. Podría agregar eso como un plus a la wcsolución.
EvergreenTree
1

Para palabras use:

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

. denota la línea actual.

También pongo lo siguiente en mi archivo .vimrc:

:cabbrev zzcc   s/./&/gn

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

Puedo teclear:

:.,+6 zzcw

y zzcwse expandirá as/\i\+/&/g

El zzcwes solo un nombre extraño que no coincidirá con nada (para mí).

Un efecto secundario es que todo el archivo está seleccionado y resaltado.

Quería poder escribir tweets de varias líneas en un archivo, asegurarme de que no hubiera demasiados caracteres y pegar el tweet en Twitter.

elademanon
fuente