Esta página puede ser redistribuida libremente bajo los términos de la licencia GPL. Vease ( GPL texto original ) o si lo prefiere (Traducción española no oficial de la GPL) Al margen de las obligaciones legales que se derivan del uso de esta licencia rogamos sea respetada la referencia a su lugar de publicación original www.ciberdroide.com. y a su autor original Antonio Castro Snurmacher (Madrid 01/01/2000).

Ausencia de Garantía

Esta ausencia de garantía se hace extensa a cualquier tipo de uso de este material y muy especialmente a las prácticas, ejercicios, y de ejemplos que encuentre en estas páginas. Deberá trabajar siempre salvo indicación contraria con un SO Linux y con un usario distinto de 'root' sin privilegios especiales. Como directorio de trabajo se procurará usar el directorio '/tmp' o algún otro que no contenga información valiosa. Tampoco se considera buena idea practicar en una máquina que contenga información valiosa.

Todo esto son recomendaciones de prudencia. En cualquier caso si algo sale mal toda la responsabilidad será únicamente suya. En ningún caso podrá reclamar a nadie por daños y perjuicios derivados del uso de este material. Para más información lea el contenido de la licencia GPL y abstengase de hacer prácticas si no está dispuesto a asumir toda la responsabilidad.

EL EDITOR VI (segunda parte)

Objetivos de esta lección
Esta lección menciona algunas posibilidades avanzadas del editor 'vi'. Se supone que el alumno ha estudiado las lecciones precedentes y en particular el capítulo anterior dedicado al editor 'vi'. Eso significa que ya sabe editar. Vamos a suponer que incluso ha practicado un poco por su cuenta. Por ello lo que vamos a explicar en este capítulo será de escasa utilidad si no ha asimilado la lección anterior.

Poco a poco vamos a ir asumiendo un mayor dominio del alumno. Ya no vamos a detallar tan a menudo paso por paso cosas que ya se han explicado y practicado más de una vez. Eso le obligará a poner un poco más de iniciativa por su parte.

Los ejemplos de las lecciones anteriores eran prácticas totalmente guiadas, comando a comando, pero a partir de ahora tendrá que probar cosas no necesariamente idénticas a los ejemplos que nosotros utilicemos.

No se preocupe. Seguro que lo hará muy bien. Si ha llegado hasta aquí es señal de haber conseguido un avance significativo en sus conocimientos, y como Linuxero se encuentra quizás a medio camino entre el novato bruto y extremadamente torpe y el repugnante listillo informático. :-)

Confiamos plenamente en su capacidad pero recuerde que nosotros no somos responsables de lo que pueda pasarle a su ordenador. Continúe practicando con un usuario distinto de root y un directorio que no contenga información valiosa.

Seguramente en esta lección aprenda cosas que algunas personas que llevan usando 'vi' durante varios años aún no conocen, pero también contiene cosas que pueden ser muy importantes para usted. No todos usamos las mismas cosas. La mayoría de los documentos que explican el uso de 'vi' lo hacen de forma muy incompleta. Nosotros no vamos a hacer un tratado completo de este editor porque necesitaríamos muchas lecciones y nos saldríamos de los objetivos del curso pero si procuraremos mostrarle un amplio abanico de posibilidades para que tenga donde elegir. En la primera lección sobre 'vi' le mostramos un juego reducido de comandos pero suficiente para defenderse. En esta lección le damos la posibilidad de convertirse en un virtuoso de este editor.

Búsquedas
Desde el modo comandos se puede usar '/' para buscar. Admite expresiones regulares. Por ejemplo si introduce '/debian.com' podría localizar una cadena 'debian-com' o 'debian:com' y no solo 'debian.com'. Recuerde que algunos caracteres como el punto el asterisco, etc tienen un significado especial y para usarlas en 'vi' hay que precederlas de '\' que actuará como carácter de escape. También hay que escapar los caracteres como por ejemplo '/' y '&' porque sin tener significado como operador de expresión regular si tiene un significado especial para 'vi' que veremos cuando expliquemos las sustituciones. No vamos a volver a explicar las expresiones regulares porque ya dedicamos una lección. Practique lo que va aprendiendo y recuerde que las expresiones regulares no funcionan igual en todas las aplicaciones. Vamos a poner varios ejemplos para su uso en búsquedas desde 'vi'. Para buscar '</TABLE>' habría que usar '/<\/TABLE>'.

Es decir que algunos caracteres no los podemos usar tal cual para buscarlos sino que hay que es caparlos. En el caso anterior hemos escapado '/'. Tenga en cuenta esto cuando intente por ejemplo buscar un carácter '$' en un texto.

Con 'n' buscará la ocurrencia siguiente de la cadena en el fichero. Con 'N' buscará la ocurrencia anterior. Una vez llegado al final comienza de nuevo la búsqueda por el principio.

También se puede empezar la búsqueda desde el primer momento en sentido ascendente usando '?' en lugar de '/'. En este caso los comandos 'n' y 'N' también funcionaran en sentido contrario que con el comando '/'.

Si usamos '/' o '?' sin nada más a continuación, se repetirá la última búsqueda.

Las expresiones regulares ofrecen grandes posibilidades como ya hemos visto pero particularmente interesantes para 'vi' pueden ser las búsquedas a principio o a final de una línea. En el ejemplo buscaremo 'El' a principio de una línea y luego 'as' al fineal de línea.

'/^El'
'/as$'

Sustituciones
Ya dispone de un resumen de todos los comandos de 'vi' que proporcionamos en el capítulo anterior así que lo mejor es presentar una serie de ejemplos explicando para que sirven.

Vamos a poner tres formas distintas de sustituir 'encarnado' por 'colorado' en las tres primeras líneas de un texto, y solo deseamos que ocurra la sustitución en la primera ocurrencia de cada línea caso. Es decir si una línea contiene varias veces la palabra 'encarnado' solo deseamos sustituir la primera.

:1,3 s/encarnado/colorado/
:1,3 s:encarnado:colorado:
:1,3 sçencarnadoçcoloradoç

Ahora de dos formas distintas vamos a sustituir en todo el texto 'encarnado' por 'colorado'. Es decir si una linea contiene varias veces la palabra 'encarnado' deseamos que la sutitución se realice en todas ellas. Para eso utilizaremos un comando similar al anterior pero finalizado en '/g'. Los ejememplos solo varían en la forma de indicar con '1,$' o con '%' la búsqueda en todo el texto.

:1,$ s/encarnado/colorado/g
:% s/encarnado/colorado/g

Ahora si sutituimos en todo el texto 'encarnado' por 'colorado' pero confirmando cada cambio manualmente. Para eso utilizaremos un comando similar al anterior pero finalizado en '/gc'. La 'g' tiene el mismo significado que en el caso anterior y la 'c' significa 'confirmación'.

:1,$ s/encarnado/colorado/gc

Vamos a usar ahora las sustituciones con expresiones regulares.

1) Poner a doble línea todo un texto.

:%s/$/\
/g

2) Eliminar blancos y tabuladores a final de linea.

:%s/[space tab]*$//

3) Eliminar blancos y tabuladores al principio de línea.

:%s/^[space tab]*//

4) Sustituir cualquier secuencia de blancos y tabuladores por un único blanco.

:%s/[space tab][space tab]*/ /

5) Poner entre paréntesis todos los números enteros de un texto.

:%s/[0-9][0-9]*/\(&\)/g

En este último hemos usado el operador '&' en la misma forma que vimos con 'sed' unas lecciones atrás. Se pueden hacer en poco tiempo cosas bastante complejas. Por ejemplo vamos a hacer un shell-script que genere otro shell-script. Para ello primero lo que haremos es escribir el programa que deseamos generar.

echo 'kkkk'
echo 'kkkk'\''hhhh'

Para generarlo bastará tratar cada línea poniendo un "echo '" al comienzo de cada línea y una comilla simple al final "'" de cada línea, pero antes escaparemos cualquier posible comilla simple que pudiera existir. Para ello editamos el texto anterior y hacemos lo siguiente:

:% s/\'/\'\\\'\'/g
:% s/^/echo \'/
:% s/$/\'/

Deberá quedarnos de esta forma.

echo 'echo '\''kkkk'\'''
echo 'echo '\''kkkk'\''\'\'''\''hhhh'\'''

Bueno lo hemos realizado con 'vi' y a pesar de lo complicado del resultado solo hemos realizado tres operaciones sencillas. Ahora ejecute este fichero y verá como obtiene el primero.

Bueno si no conoce C no le entusiasmará este otro ejemplo pero eso de hacer programas que generan programas nos sirve para practicar las sustituciones usando 'vi'. Podemos escribir el programa en C que deseamos generar y luego tratarlo sustituyendo todas las '\' por '\\' y todas las '"' por '\"'. Es decir escapamos esos dos caracteres que darían problemas más tarde. Luego añadimos a principio de cada línea 'printf("' y finalizamos cada línea con '\n");'

Las sustituciones que acabamos de mencionar serían de esta forma.

:% s/\\/\\\\/g
:% s/"/\\"/g
:% s/^/printf("/
:% s/$/\\n");/

Edición de varios ficheros secuencialmente
Al editor 'vi' se le puede pasar como argumento no solo un fichero sino varios para ser editados en secuencia. Por ejemplo:

$ vi fich1 fich2 fich2

Bueno esto puede ser más útil de lo que parece a simple vista. Vamos a suponer que tenemos que modificar una gran cantidad de ficheros para sustituir en muchos de ellos la cadena 'acastro' por la cadena 'A.Castro' pero tampoco lo podemos hacer de forma automática porque nos conviene ver caso a caso. Por eso pasamos a 'vi' el resultado de una búsqueda con 'grep'.

$ vi `grep -il acastro *.txt`

Una vez dentro del editor hacemos lo siguiente.

:args

El comando ':args' nos informará del nombre de los ficheros que vamos a editar secuencialmente. Intente probar esto creando sus propios ficheros de prueba. Ya sabe como hacerlo. Conviene que todos ellos tengan una cadena idéntica para ser localizada con grep. Una vez que el editor 'vi' este preparado para editar secuencialmente varios ficheros busque la cadena con el operador '/' y aunque pasemos a editar el siguiente fichero se conservará almacenada la cadena de búsqueda. Esta forma de trabajar facilita mucho la modificación de varios ficheros.

Para editar ficheros secuencialmente le conviene tener en cuenta los siguientes comandos. Algunos no los habíamos comentado todavía.

:args   Obtiene la lista de los ficheros
:next   Pasa al fichero siguiente
:prev   Vuelve al fichero anterior
:rewind Vuelve al primero
:rewind! Vuelve al primero abandonando los cambios en el fichero actual
:w      Salva los cambios del fichero anterior
:q      Sale del editor. (Solo si ya se han editados todos)
:q!     Sale del editor incondicionalmente.

Edición simultanea de ficheros
Podemos pasar de la edición de un fichero a la edición de otro usando ':e fichero' pero antes deberemos salvar el contenido de la edición actual. También podemos forzar el paso a editar otro fichero con ':e! fichero' pero en ese caso se perderán las modificaciones realizadas. Usando ':e#' volvemos a retomar la edición del fichero anterior situados en la misma línea donde lo dejamos. Intente practicar lo siguiente editando unos ficheritos de prueba.

:e fich1
:w
:e fich2
:e! fich3
:e#

Visualización de caracteres de control
En 'vi' los caracteres de control se visualizan como un acento circunflejo y una letra. Por ejemplo <CTRL+K> se visualizará como '^K' y la manera de distinguir un carácter circunflejo real seguido de una 'K' es moviendo el cursor para ver si de desplaza uno o dos caracteres cuando pasamos por el carácter circunflejo. También se usa con similar significado el carácter tilde '~' pero para caracteres de 8 bits.

Introduciendo caracteres de control en el texto
Imaginemos que deseamos introducir un carácter de control para provocar un salto de página en la impresora. Para ello deberemos introducir un <CTRL+L> que será visualizado como '^L'. La forma de hacerlo es pulsar desde el modo inserción el carácter <CTRL+V> y a continuación el carácter <CTRL+L>. Es decir el carácter <CTRL+V> actúa como carácter de escape. Podemos pulsar <CTRL+V> y luego una tecla de función, u otras teclas especiales.

También se pueden buscar caracteres de control. Para ello tambíen hay que introducirlos usando <CTRL+V>.

Edite un fichero de prueba y proceda a poner varios saltos de página en distintos lugares. Luego busque con '/' y con '?' los saltos de página. Pruebe a insertar los códigos de las teclas <ENTER> y <ESC>, mediante <CTRL+V><ENTER> y <CTRL+V><ESC> respectivamente. Deberán aparecer como '^M' y como '^['.

El comando tilde
El comando '~' sustituye el carácter situado bajo el cursor de mayúscula a minúscula y viceversa avanzando luego el cursor.

Operaciones con bloques
Se pueden marcar hasta 26 posiciones ('a'..'z') para un conjunto de uno o mas ficheros editados simultáneamente. Permite trabajar marcando principio y fin de bloques para mover, copiar o borrar en varios ficheros. Se pueden usar las marcas en cualquier comando en sustitución de '.', '$', o los números de línea como ya hemos visto. La ventaja es que si estamos insertando o borrando líneas tendríamos que volver a comprobar los números de líneas. Por el contrario si hemos colocado una marca en una línea continuará en esa línea mientras no la eliminemos. Para colocar una marca podemos situarnos con el cursor en la línea deseada y luego hacer ':k <letra-minúscula>' ':ma <letra-minúscula>' ':ma <letra-minúscula>' o directamente sin pasar al modo ex mediante 'm <letra-minúscula>'. Para practicar con ello edite un fichero de prueba y coloque varias marcas en distintas líneas. Luego realice distintas operaciones como por ejemplo el borrado de bloques. Compruebe como desaparece una marca cuando se borra la línea que la contiene. Las marcas no se ven pero si intenta usar una marca que no existe obtendrá un error. Compruebe como reaparece la marca cuando deshace la operación con 'u' (undo). Algunas formas de utilización de marcas son las siguientes.

:'a,'b de
:'b,'b+1 de
:'a,. de
:'a,'b co 'c
:'a,'b mo 'c

También podemos posicionarnos en el lugar de una marca pulsando comilla-simple y <letra-minúscula> desde el modo comandos. Un detalle interesante es que siempre podemos volver a la línea donde nos encontrábamos, la última vez que dimos un salto de posición en el texto. Para ello pulsamos '' (comilla-simple dos veces).

Repetición del último comando
Cuando hay que hacer varias veces la misma cosa resulta tremendamente útil poder repetir el último comando. Imaginemos que desde el modo de comandos hacemos en una línea 'RLínea <ESC>' para sustituir 6 caracteres por la cadena 'Línea ' Inmediatamente después de ello y antes de hacer ninguna otra cosa podríamos situarnos en otra línea y pulsar '.' (punto) para repetir ese mismo comando y luego cambiar a otra y otra línea y volver a pulsar '.' punto a cada vez para efectuar el mismo cambio en varios sitios. Tambíen mencionamos la posibilidad de ejecutar un comando del sistema operativo lanzando una sub-shell. Pues bien este tipo de comandos ': <comando>' puede ser repetido usando ':!!'

Tabulación
El carácter con la tecla <TAB> o con el carácter <CTRL+I> insertará un carácter de tabulación. El ancho de la tabulación será por defecto igual a 8 espacios. Esto puede ser variado por ejemplo a 5 con ':set tabstop=5'. Si deseamos añadir un tabulador al principio de línea en las siguientes 7 lineas a la posición del cursor podemos hacer. '7>>'. Tambíen se podría haber hecho lo mismo con ':.,.+7 >>'. Para insertar un tabulador a principio de cada línea del texto sería ':% >>' Cuando se usa el editor para editar fuentes de programas puede resultar útil usar la indentación automática. 'set ai' para eliminar la indentación automática usaremos 'set noai'. Si en alguna ocasión necesita sustituir todos los tabuladores por caracteres en blanco use el comando 'expand'. No es un comando de 'vi' sino del SO. Consulte con el man su sintaxis y las distintas opciones. Para hacer una prueba edite un fichero insertando tabuladores y luego conviertalo de la siguiente forma.

expand fichero > ficheroexpandido.

Abreviaturas
En 'vi' hay muchos detalles pensdos a ahorrar pulsaciones de declas. Vamos a ver el comando ':ab' Si está acostumbrado al uso de abreviaturas le resultará muy práctico. Puede definir las abreviaturas que quiera y una vez tecleadas en modo entrada de dados (insercion o sobrescritura) serán sustituidas por la cadena que desee. Vamos a usar dos abreviaturas una 'ci' para 'Ciberdroide Informática' y otra 'INMHO' para 'en mi humilde opinión'. También vamos a listar las abreviaturas definidas.

:ab ci Ciberdroide Informática
:ab INMHO en mi humilde opinión
:ab

Use sus propias abreviaturas en un texto y observe como la abreviatura no será interpretada si la secuencia de caracteres forma parte de una palabra.

Macros
Es posible programar macros. Por ejemplo vamos a hacer una macro que mueva 4 líneas al final del fichero

:map xxx 4dd:$^Mp
:map

Con esta macro ocurrirá algo. En primer lugar si teclea las tres 'x' seguidas se ejecutarán los comando '4dd' (borrar cuatro lineas), ':$<ENTER>' (ir a la última línea) y 'p' (recuperar el contenido del buffer) Si pulsamos una sola 'x' notaremos que no pasa nada inmediatamente pero luego se eliminará un carácter tal y como ocurre normalmente. Es decir la macro tiene un tiempo para ser tecleada completamente en caso contrario no actúa. Para ver todas las macros definidas usaremos ':map'

Podemos eliminar la macro que acabamos de crear con 'unmap'

:unmap xxx 

Muchas veces se usan las macros para definir comandos asociados a teclas especiales. Para ello hay que conocer la secuencia de caracteres que envían esas teclas. Si en modo inserción usamos <CTRL+V><F2> obtendremos '^[[[B'. Pero también podemos usar '<F2>' para definir macros. Vamos a poner algunos ejemplos prácticos.

F2 (Filtro PGP) Firmar.

:map [[B 1G!Gpgp -satf 2>/dev/tty

Sería lo mismo si usaramos '<F2>' en lugar de '^[[[B'.

:map <F2> 1G!Gpgp -satf 2>/dev/tty

F3 (Filtro PGP) Encriptar

:map [[C 1G!Gpgp -eatf 2>/dev/tty 

F4 (Filtro PGP) Desencriptar y comprobar firma

:map [[D 1G!Gpgp  2>/dev/tty; sleep 7

F5 (Filtro ispell) Corrector ortográfico.

:map [[E :w
:!ispell % 
:e!

Opciones de vi
Sería absurdo pretender explicar en una lección todo el editor 'vi'. Tampoco hay necesidad de ello. Hay montones de opciones y ya hemos visto algunas. Si el editor es 'vim' en lugar de 'vi' el número de posibilidades es aun mayor. Puede ver las opciones disponibles y sus valores actuales usando el comando ':set all' desde el modo de comandos. No se asuste. No ha que conocerlas todas. Hay opciones que seguramente la persona que las implementó ya ha olvidado para que sirven. Una opción se puede indicar muchas veces de dos formas. Una en forma completa y otra en forma abreviada. Por ejemplo ':set nu' en lugar de ':set number' y para desactivar la opción se suele usar la misma opción precedida de 'no'. Por ejemplo ':set nonu' o ':set nonumber'. Las opciones que deben tomar un valor numérico se establecen con el nombre de la opción seguida de '=' y el valor. Por ejemplo ':set tabstop=5'

Configuración del editor
El fichero más estándar para configurar 'vi' en cualquier SO de tipo Unix es '~/.exrc'. Como alternativa se puede usar ficheros más específicos para el editor concreto que estemos usando. Por ejemplo en el caso de 'vim' tenemos '~/.vimrc'. Compruebe si existe un ejemplo '/etc/vimrc' en su Linux y mire su contenido. Se trata de un fichero de ejemplo para copiarlo en ' ~/.vimrc' Contiene algunas configuraciones que pueden resultar útiles. El carácter comilla doble '"' se usa para considerar el resto de la línea como un comentario. Si considera que el editor tiene un comportamiento que usted considera incómodo quizás se deba a la existencia de algunas opciones que no se adaptan al uso que usted da a su editor. Por ejemplo para editar programas C puede resultar cómodo la auto- indentación pero no le gustará que parta las líneas automáticamente cuando excedan un determinado ancho. También es buena idea incluir en su fichero de configuración las abreviaturas y las macros que desee usar. Ya hemos visto algunas y seguramente ya se ha preguntado como hacer para no tener que introducirlas cada vez. Es bueno perder un poco de tiempo en personalizar el editor.

Tag
Para editar fuentes C por ejemplo resulta muy practico. Supongamos que tenemos un fuente llamado pingpong.c. Crearemos en primer lugar un fichero tags ejecutando "ctags pingpong.c" (ver ctags(C)). Se crea un fichero tags que contendrá por ejemplo lo siguiente:

plot	pingpong.c	?^plot(x, y, ch)$?
salir	pingpong.c	?^salir(s)$?

Con ello se referencian las funciones. Para editar el fichero podemos hacer vi -tplot. Aparecera el cursor en la posición de esa función. Si introducimos :ta salir desde el modo de comandos nos situaremos en esa función. Se pueden crear tags para varios ficheros simultáneamente mediante ctags */*.[cfg] (ver ctags(C)). De esta forma podríamos editar cómodamente varios fuentes.

Test
Puede comprobar sus conocimientos respondiendo el siguiente test.
Para ello seleccione las opciones que se ajusten a la verdad y luego pulse el boton para ver el resultado de su test.

1 Para localizar '$US' pulsaremos '/$US' desde el modo comandos.
2 Los signos '.', '/', '(', ')', '&', '^', '*', '$', '?', '+' y '\' necesitan ser escapados con '\' para la búsqueda en 'vi'.
3 Para localizar líneas vacías haremos '/^$'
4 Pulsando 'ma b' desde el modo comandos marcamos con la letra 'b' la posición actual.
5 Si definimos una macro para la secuencia 'ddd' no podremos usar el comando 'dd'
6 Si definimos una abreviatura 'edi' para la palabra 'edición' obtendremos 'edicióntar' cuando intentemos escribir 'editar'.
7 Para ir a la marca 'b' pulsaremos " 'b " (comilla simple 'b')
8 Para copiar al final de texto desde una linea anterior a la marca 'a' hasta la marca 'b' habría que hacer " :'a-1,'b co $ "

Resultado del test

Si quiere hacernos llegar alguna duda, aclaración,
crítica, o contribución personal, utilice nuestro
formulario de contacto y nosotros le contestaremos
contacto