Lo utilizo directamente desde la consola de comando. En este ejemplo elimino todos los procesos de la cuenta (colono). Comando en una línea.
|
1 |
for i in `ps -fu colono | awk '{print $2}'`; do kill -9 $i; done |
Lo utilizo directamente desde la consola de comando. En este ejemplo elimino todos los procesos de la cuenta (colono). Comando en una línea.
|
1 |
for i in `ps -fu colono | awk '{print $2}'`; do kill -9 $i; done |
Para este ejemplo ingresaremos una lista de servidores en una archivo txt (remotes.txt). El SCRIPT leerá cada servidor del archivo y procederá a ejecutar el SCRIPT LOCAL (script.sh) en los servidores remotos.
|
1 2 3 4 5 |
#!/bin/bash servidores=$(cat remotes.txt) for host in $servidores; do ssh $host 'bash -s' < script.sh done |
Vi ha sido el primer editor de texto a pantalla completa para sistemas Unix . Además fue creado con la intención de que fuese sencillo en su uso y ligero para no cargar sobremanera el sistema. Para aquellos acostumbrados a usar editores de texto mediante en entornos gráficos, puede resultar un poco abrupto y complejo su aprendizaje, pero si bien porque estamos al cargo de un servidor Linux o porque nuestro entorno gráfico está dando problemas y no carga, deberíamos ser capaces de editar ficheros desde un editor como Vi / Vim.
Veamos los diferentes comandos básicos de movimiento, inserción y borrado (siempre en modo comando):
| Comando | Significado |
| h | Mover el cursor a la izquierda. |
| j | Mover el cursor hacia abajo. |
| k | Mover el cursor hacia arriba. |
| l | Mover el cursor hacia la derecha. |
| i | Insertar texto en la posición actual del cursor (Insert), pasando a Modo Inserción. Se permanece en modo inserción hasta que se sale explícitamente de él. |
| ESC | Salir del modo inserción y volver a modo comando. En modo comando, permite cancelar muchos de los comandos que se están ejecutando. |
| x | Borrar el caracter bajo el cursor (equivale a la tecla Del/Supr). |
| X | Borrar el caracter a la izquierda del cursor (equivale a la tecla Borrar/Backspace). |
| J | Juntar la línea actual con la siguiente (Join), eliminando el retorno de carro entre ellas. |
| u | Deshacer la última acción (Undo). Si lo pulsamos más veces desharemos acciones anteriores. |
| CTRL+R | Rehacer la última acción (Redo). Si lo pulsamos más veces reharemos acciones posteriores deshechas. |
| a | Insertar texto en la siguiente posición tras el cursor (Append). Es similar a i, salvo que el texto no se inserta en la posición actual del cursor sino a su derecha. |
| A | Poner el cursor al final de la línea y pasar a modo inserción (añadir texto al final). |
| o | Crear una línea vacía, en blanco, bajo la línea actual, y pasar a modo inserción con el cursor posicionado en dicha línea. Es mucho más cómodo que (como en otros editores) tener que pulsar FIN y ENTER para crear una línea en blanco. |
| O | Crear una línea vacía, en blanco, sobre la línea actual. Sería el equivalente en otros editores a ARRIBA, ARRIBA, FIN, ENTER. |
| dd | Borrar la línea actual (sobre la que está el cursor). |
| D | Borrar desde la posición actual del cursor hasta el final de la línea. |
En la mayoría de comandos de Vim podemos añadir counts, que es como se conoce a los repetidores del comando. El count es un número que se teclea antes del comando para que se repita varias veces. Unido a la potencia del modo comando nos da mucho juego para la edición. Veamos unos cuantos ejemplos:
| Comando | Significado |
| 10dd | Repetir 10 veces el comando dd, es decir borrar 10 líneas empezando desde la línea actual. Es el equivalente a teclear manualmente 10 veces dd, y mucho más rápido que seleccionar 10 líneas a mano con ratón o cursores. |
| 5x | Repetir 5 veces el comando x, es decir, borrar 5 caracteres empezando desde el carácter actual. Equivale a pulsar manualmente 5 veces el comando x. |
| 60i-<ESC><ENTER> | Insertar 60 guiones consecutivos. Este comando se teclea en modo comando pulsando 6, 0, i, guión, y pulsando la tecla ESCAPE y luego pulsar ENTER para validar el comando. Al hacerlo, estamos diciendo que se repita 60 veces la secuencia i guión ESCAPE, es decir, pasar a modo inserción, escribir un guión, y volver al modo comando pulsando ESCAPE. El 60 que hay delante lo repite 60 veces, con lo cual tenemos 60 guiones en pantalla. ¿No es mucho más cómodo al programar, para introducir separadores de comentarios, que pulsar el guión 60 veces o durante varios segundos mientras miramos la columna en la que estamos? |
| 10iHola<ENTER><ESC><ENTER> | (pulsar ESC y ENTER como las teclas ESC y ENTER, no tecleando la cadena) Aparece la palabra Hola 10 veces en pantalla, cada vez en una línea propia. Su significado, al igual que en el ejemplo anterior, sería repite 10 veces la secuencia i, Hola, ENTER, ESC, que pasa a modo inserción, escribe Hola, pasa a la siguiente línea con ENTER, y vuelve a modo comando. |
Los comandos básicos a la hora de editar ficheros son:
| Comando | Significado |
| :w | Grabar los cambios del fichero actual. |
| :w nombre | Grabar el contenido actual del buffer en un fichero de nombre nombre. |
| :q! | Salir del editor sin grabar ningún cambio en el fichero actual (descartando cualquier cosa que hayamos hecho desde su apertura o última vez que grabamos). |
| ZZ | Salir del editor grabando los cambios en el fichero actual. También sirve 😡 o :wq!. |
| CTRL+G | Obtener información en la barra de estado del nombre del fichero que estamos editando, línea actual, número de líneas, en qué porcentaje del fichero estamos, y número de columna. |
| :e fichero | Abrir un fichero en el buffer actual (si está vacío) o en uno nuevo (si tenemos el buffer actual en uso) |
En el caso de que hayamos abierto con :e más de un fichero, podemos movernos entre ellos con:
| Comando | Significado |
| :bn | Siguiente buffer (fichero). |
| :bp | Anterior buffer (fichero). |
| :bd | Cerrar buffer (fichero) actual. |
En Vim podemos aplicar las búsquedas, borrados y modificaciones no sólo a la línea actual o a la totalidad del documento, sino que también podemos hacer referencia a porciones del texto:
| Rango definido con… | Significado |
| % | Todo el documento. |
| n,M | Bloque de líneas desde la n a la M. |
| ‘a,’b | Bloque de líneas entre las marcas a y b. |
| ‘<,’> | Bloque de texto seleccionado en modo visual. |
Por ejemplo:
:17,20d -> Borrar líneas de la 17 a la 20
:’a,’b s/hola/adios/g -> Cambiar cadena en el bloque entre las marcas ‘a y ‘b
Hemos dicho que con el modo comando de Vim tenemos muchas más opciones que con el modo inserción (o que en otros editores), pero hasta ahora sólo hemos visto una ínfima parte de las posibilidades de Vim. Como veremos ahora, no tenemos porqué movernos carácter a carácter, línea a línea o página a página. Vamos a poder movernos a la palabra anterior y la siguiente, a cualquier parte del fichero, etc.
| Comando | Significado |
| w | Mueve el cursor al principio de la siguiente palabra de la línea actual, o de la siguiente línea si estamos en la última palabra de la línea. |
| b | Mueve el cursor al principio de la anterior palabra de la línea actual, o de la anterior línea si estamos en la primera palabra de la línea. |
| e | Igual que w, pero coloca el cursor en el último carácter de la siguiente palabra (al final de la palabra en lugar de al principio). |
| ge | Igual que b, pero coloca el cursor en el último carácter de la anterior palabra. |
| W, B, E y gE | Iguales que w, b, e y ge, pero con una peculiaridad. En mayúsculas, nos movemos de palabra en palabra considerando como separador de palabra sólo los espacios en blanco y retornos de carro, mientras que en minúsculas, Vim utiliza un modo inteligente con más separadores de palabras, como el guión o la barra. Por ejemplo, en el caso de tener la frase cadena1-cadena2 cadena3 o cadena1/cadena2 cadena3 con el cursor sobre el primer carácter, w avanzaría el cursor hasta primera letra de cadena2, mientras que W lo avanzaría hasta la primera letra de cadena3. |
| $ | Mueve el cursor al final de la línea (equivalente a la tecla Fin). |
| 0 | Mueve el cursor al principio de la línea (equivalente a la tecla Inicio). |
| ^ | Mueve el cursor al primer carácter no blanco de la línea. Perfecto a la hora de programar, cuando queremos corregir cosas en el código, normalmente indentado con espacios o tabuladores al principio de las líneas. |
| { | Mueve el cursor al anterior párrafo (o bloque de código). |
| } | Mueve el cursor al siguiente párrafo (o bloque de código). |
| f<carácter> | Realiza una búsqueda en la línea actual del carácter indicado. Por ejemplo, fx mueve el cursor a la primera aparición del carácter x desde la posición actual. Muy útil para ir rápidamente a partes concretas de una línea sin llevar la mano al ratón (por ejemplo, para corregir una h que sea un error ortográfico, pulsando fh. |
| F<carácter> | Igual que el comando anterior, pero realizando la búsqueda hacia atrás en la línea actual (empezando desde la posición actual del cursor). |
| t<carácter> y T<carácter> | Similares a f<carácter> y F<carácter> salvo que posicionan el cursor en el carácter anterior a la letra buscada. |
| ; y , | Repiten la ejecución del último comando f, F, t o T hacia adelante (;) o hacia atrás (,). |
| ESC | En el caso de búsquedas f, F, t o T, permite cancelar la búsqueda. |
| % | Al pulsarlo sobre un paréntesis abierto o cerrado (, ), corchete abierto o cerrado [, ] , o llave abierta o cerrada {, }, mueve el cursor a la pareja de dicho elemento. Por ejemplo, si estamos programando y queremos saber cuál es el paréntesis que cierra el paréntesis sobre el cual está el cursor, pulsamos % y vim nos lleva directamente a él. Como también funciona con corchetes y llaves, podemos encontrar fácilmente qué llave cierra un bloque de código, o qué if/for/while/loquesea es el que ha abierto una determinada llave de cierre en un programa en C que estemos depurando. |
| <NUMERO>G | Ir a la línea número NUMERO del documento. Por ejemplo, 100G nos llevaría a la línea número 100. Es especialmente útil a la hora de programar, cuando tenemos que ir a líneas concretas del programa donde el compilador nos ha reportado errores. |
Si no estamos programando pero queremos utilizar números de líneas (porque nos parece más cómodo), podemos hacer uso de las siguientes opciones de modo comando:
| Comando | Significado |
| :set number | Activa la numeración de líneas. |
| :set nonumber | Desactiva la numeración de líneas. |
| :set ruler | Activa en la barra de estado una indicación de la columna y fila actual. |
Cualquiera de estas opciones las podemos poner en nuestro fichero .vimrc para que se apliquen a todos los documentos que editemos, o cambiarlas en cualquier momento en modo comando.
| Comando | Significado |
| gg | Ir a la primera línea del documento (equivale a 1G) |
| G | Sin número delante, G nos lleva a la última línea del documento. |
| <NUMERO>% | Nos lleva a un porcentaje concreto del fichero. Por ejemplo 50% nos lleva a la mitad del fichero, y 95%, casi al final del mismo. |
| CTRL+F | Scrollea una pantalla completa hacia adelanta (F de Forward). |
| CTRL+B | Scrollea una pantalla completa hacia atrás (B de Backward). |
| CTRL+E | Scrollea la pantalla en una sóla línea hacia arriba. |
| CTRL+Y | Scrollea la pantalla en una sóla línea hacia abajo. |
| CTRL+U | Scrollea media pantalla de texto hacia abajo (el equivalente a hacer medio RePág). Puede sonar raro el hecho de scrollear medias pantallas, pero en determinadas situaciones puede ser útil (si no queremos perder de vista texto ya leído cuando avanzamos, por ejemplo). |
| CTRL+D | Scrollea media pantalla de texto hacia arriba (como hacer medio AvPág). Permite así avanzar el documento media página sin perder de vista el texto donde está el cursor. |
| zz | Sin modificar la posición actual del cursor, modifica la ventana de visualización del fichero de forma que la línea actual acabe centrada en pantalla y podamos ver el contexto. Por ejemplo, supongamos que estamos en la parte de abajo de la pantalla con el cursor en la última línea y necesitamos ver con facilidad y claridad qué líneas hay sobre y bajo ella. En otros editores usaríamos la tecla de Abajo hasta centrar un poco la línea en pantalla y luego subiríamos hacia arriba para volver a la línea en que estábamos. En Vim basta con pulsar zz para centrar la línea actual en pantalla sin mover la posición del cursor para nada. |
| zt | Igual que zz pero posicionando la línea en la parte superior de la pantalla (t viene de top) lo que nos permite ver con claridad la línea actual y muchas líneas posteriores. |
| zb | Igual que zt, pero posicionando la línea en la última posición de la ventana de pantalla, lo que nos permite ver la línea actual y muchas líneas anteriores. En ambos 3 comandos no se modifica la posición del cursor en el documento, sólo la manera de verlo en pantalla. |
De nuevo podemos utilizar multiplicadores en todos los comandos anteriores para evitarnos pulsaciones innecesarias de teclas:
| Comando | Significado |
| 20w | Avanzar 20 palabras. |
| 3fx | Avanzar el cursor a la tercera aparición de la letra x en la línea actual, desde la posición del cursor. |
Por último, respecto a comandos de movimiento, existen 3 comandos muy especiales que nos permiten posicionar el cursor al principio, medio y final de la pantalla. Ojo, no principio, medio y final del fichero, sino de la pantalla, de lo que vemos en nuestro monitor:
| Comando | Significado |
| H | Posiciona el cursor al principio de la pantalla (sin hacer scroll de ella). |
| M | Posiciona el cursor en el centro de la pantalla. |
| L | Posiciona el cursor en la parte baja de la pantalla. |
| Comando | Significado |
| 4dw | Repetir 4 veces dw, es decir, borrar 4 palabras. |
| d4w | Borrar el resultado de 4w, es decir, borrar el resultado de moverse 4 palabras. |
Como algunos modificaciones y operadores se utilizan tanto, Vim nos proporciona unos atajos de una sola letra para ejecutarlos:
| Atajo | Equivalente | Significado |
| x | dl | Borrar el carácter bajo el cursor. |
| X | dh | Borrar el carácter a la izquierda del cursor. |
| D | d$ | Borrar hasta el final de la línea. |
| C | c$ | Cambiar el texto hasta el final de la línea. |
| s | cl | Cambiar un carácter. |
| S | cc | Cambiar la línea completa. |
Gracias a la potencia de Vim, entre operadores y multiplicadores podemos hacer la edición muchísimo más rápida. Veamos algunos comandos más avanzados:
| Comando | Significado |
| dw | Borrar desde el cursor hasta el final de la palabra actual. Por ejemplo, si estamos encima de la letra m de la palabra automóvil, ejecutando dw quedaría tan sólo la palabra auto. Recuerda que w avanza hasta el siguiente separador de palabra y W hasta el siguiente espacio entre palabras, de modo que también podemos usar dW si es lo que nos interesa. |
| db | Borrar desde el cursor hasta el principio de la palabra actual. Por ejemplo, si estamos encima de la letra m de la palabra automóvil, ejecutando db quedaría tan sólo la palabra móvil. |
| diw | Borrar la palabra bajo el cursor (completa), desde su principio hasta su final, estemos donde estemos dentro de la palabra. |
| daw | Borrar la palabra bajo el cursor, igual que diw, pero en este caso si existe un espacio tras la palabra también lo borra. |
| dis | Borrar la frase (no línea, sino frase hasta el próximo punto) sobre la que está el cursor. |
| das | Igual que dis, pero si existe un espacio tras la frase también lo elimina. |
| dG | Borrar desde la posición actual del cursor hasta el final del fichero. |
| dgg | Borrar desde la posición actual del cursor hasta el principio del fichero. |
Otra de las operaciones básicas de búsqueda es el reemplazo de cadenas, es decir, cambiar en todo el fichero (o en una parte del mismo) una cadena por otra. Esto se hace con el comando de sustitución :s.
Por ejemplo, para cambiar todas las apariciones de la cadena hola por adios, haremos:
:%s/hola/adios/g
Este comando viene a decirle a Vim que sustituya (s), en todo el fichero (%), la cadena hola por adios, y que si en una línea encuentra más de una aparición de hola, que cambie todas (g). Si quitamos la g, sólo cambiaremos la primera aparición de hola en cada frase. Si además de la g añadimos una i, se hará una comparación que no distingue mayúsculas de minúsculas.
Recordad que en el caso de usar expresiones regulares tendremos que escapar ciertos caracteres especiales, como los puntos, las barras, etc, en la parte de búsqueda. Por ejemplo:
:%s/hola\.hola/adios.adios/g
El resumen del uso básico de la sustitución en Vim es:
| Comando | Significado |
| :%s/cad1/cad2/ | Reemplazar en cada línea del fichero la primera aparición de cad1 (sea cadena o expresión regular) por cad2. |
| :%s/cad1/cad2/g | Reemplazar en cada línea del fichero todas las apariciones de cad1 por cad2. |
| :%s/cad1/cad2/gi | Reemplazar en cada línea del fichero todas las apariciones de cad1 por cad2, sin distinguir mayúsculas y minúsculas |
| :%s/cad1/cad2/gc | Reemplazar en cada línea del fichero todas las apariciones de cad1 por cad2 pidiendo confirmación en cada reemplazo. |
| :%s/cad\(regexp\)ena/cad\1ena2/gc | Utilizar en la sustitución parte de la búsqueda por expresión regular |
| :n,Ncomando | Cualquiera de los 3 ejemplos anteriores, sobre un rango de líneas. |
| :'<,’>comando | Cualquiera de los ejemplos anteriores, sobre la selección «visual» actual. ‘<,’> aparece cuando tenemos un texto seleccionado y pulsamos «:». |
| :’a,’bs/cad1/cad2/g | Realizar la sustitución en el texto entre 2 marcas (a y b en el ejemplo). |
| :%s//CAD2/g | Reutilizar la última búsqueda realizada para el reemplazo (búsqueda vacía en %s) |
A continuación mostramos una serie de ejemplos basicos útiles que no tienen cabida en otra sección pero que pueden resultar interesantes si el lector no los ha deducido ya para realizar una tarea concreta:
En el caso que tengamos un texto y queramos transformar la totalidad de a a A lo haremos del siguiente modo:
|
1 |
echo "Esto es una ejemplo de tr para el blog geekland" | tr 'a' 'A' |
En el caso que queramos reemplazar todas las vocales de una frase de minúscula a mayúscula lo podemos hacer del siguiente modo:
|
1 |
echo "Esto es una ejemplo de tr para el blog geekland" | tr 'aeiou' 'AEIOU' |
En el caso que queramos transformar la totalidad de letras mayúsculas a minúsculas lo podemos hacer del siguiente modo:
|
1 |
echo "Esto es una ejemplo de tr para el blog geekland" | tr 'a-z' 'A-Z' > geekland.txt |
Si queremos también podemos añadir una línea nueva al fichero geekland.txt que sea igual que la primera pero en minúscula siguiendo el siguiente procedimiento:
|
1 |
cat geekland.txt | tr 'A-Z' 'a-z' >> geekland.txt |
Si ejecutamos el siguiente comando:
|
1 |
echo "Esto es un ejemplo de tr para el blog geekland" | tr 'a-z' 'AB' |
Vemos que ha ocurrido lo siguiente:
La letra a se reemplaza por la A. La b por la B y a partir de aquí la c, e, f… hasta llegar la z se reemplazarán por la B.
Si queremos evitar este comportamiento podemos usar la opción -t o truncate. Si ejecutamos el mismo comando añadiendo la opción -t:
|
1 |
echo "Esto es un ejemplo de tr para el blog geekland" | tr -t 'a-z' 'AB' |
Vemos que ha ocurrido lo siguiente:
La letra a se reemplaza por la A. La b por la B y a partir de aquí no se reemplazará ninguna otra letra. El comportamiento ahora será de este modo gracias a la opción -t. Por lo tanto la opción -t hace que la longitud del primero de los argumentos introducidos en el comando tr sea igual que la del segundo argumento.
Nota: Con la opción -t el primero de los argumentos introducidos del comando tr tiene que tener una longitud igual o superior al segundo de los argumentos.
Si queremos borrar todas las vocales mayúsculas y minúsculas de una frase y que sean reemplazadas por un espacio en blanco lo haremos mediante la opción tr -d. Un ejemplo de lo que acabo de citar es el siguiente:
|
1 |
echo "Esto es un ejemplo de tr para el blog geekland" | tr -d 'aeiou' | tr -d 'AEIOU' |
Si quisiéramos que las vocales borradas fueran reemplazadas por espacios en blanco deberíamos haber usado el siguiente comando:
|
1 |
echo "Esto es un ejemplo de tr para el blog geekland" | tr 'aeiou' ' ' |
Para borrar todo el contenido de una frase excepto las vocales aeiou, tendremos que usar la opción -c. La opción -c o complemento vendría a actuar como lo contrario a la orden que introducimos en el comando. Por lo tanto para borrar todas las letras que no sea vocales de una frase lo haremos del siguiente modo:
|
1 |
echo "Esto es un ejemplo de tr para el blog geekland" | tr -cd 'aeiou' |
Para borra todos los caracteres que no son legibles, se utiliza el siguiente comando :
|
1 |
head /dev/urandom | tr -cd '[:print:]\n' |
Nota: Mediante la opción -cd '[:print:]' estamos diciendo que se borre todo carácter que no se imprimible/legíble. Además la opción \n hará que al finalizar la tarea el cursos de la terminal quede ubicado en una nueva línea.
Para borra todo lo que no sea un digito o numero se realizara con el siguiente comando :
|
1 |
echo "Esto es un ejemplo de tr para el blog gee1kland 1234" | tr -cd '[:digit:]\n' |
Si por lo contrario quieren borrar la totalidad de números que aparecen a la frase tan solo tendrían que eliminar la opción -c complemento y obtendrían el siguiente resultado:
|
1 |
echo "Esto es un ejemplo de tr para el blog gee1kland 1234" | tr -d '[:digit:]\n' |
En ocasiones escribimos rápido y es posible que por error escribamos 2 caracteres repetidos de forma consecutiva. Un ejemplo de lo que acabo de citar es el siguiente:
Esto es un ejeeemplo de tr para el blog.
En el ejemplo vemos que a la palabra ejemplo le sobran dos e. Para eliminarlas lo podemos hacer con la opción -s Squeeze del siguiente modo:
|
1 |
echo "Esto es un ejeeemplo de tr para el blog geekland" | tr -s 'e' |
Si tuviéramos una frase con exceso de espacios, como por ejemplo la siguiente:
|
1 |
El comando tr es útil en determinados casos |
Y quisiéramos eliminar los espacios sobrantes lo haríamos del siguiente modo:
|
1 |
echo "El comando tr es útil en determinados casos" | tr -s [:space:] |
En el ejemplo que propondremos a continuación tenemos 3 palabras separadas por un espacio:
joan carles geekland
Si queremos transformar este espacio por un tabulación lo haremos usando la opción [:space:] y \t del siguiente modo:
|
1 |
echo "joan carles geekland" | tr [:space:] '\t' |
La opción \t añade una tabulación horizontal. Si quisiéramos añadir una tabulación vertical lo haríamos con la opción \v del siguiente modo obteniendo un resultado parecido al siguiente:
|
1 |
echo "joan carles geekland" | tr [:space:] '\v' |
Si tenemos una frase, que obviamente está compuesta por palabras separadas por espacio, podemos separar cada una de las palabras en una nueva línea usando la siguiente sintaxis:
|
1 |
echo "joan carles geekland" | tr [:space:] '\n' |
Obviamente este artículo únicamente detalla algunas de las opciones del comando tr.
Articulo obtenido desde la siguiente página : «https://learnxinyminutes.com/docs/es-es/awk-es/».
Usando el buscador, puedes obtener más códigos útiles del lenguaje AWK..
AWK es una herramienta estándar en cada sistema UNIX compatible con POSIX. Es como un Perl restringido, perfecto para tareas de procesamiento de texto y otras necesidades de scripting. Tiene una sintaxis similar a C, pero sin puntos y comas, manejo manual de memoria y tipado estático. Puedes llamarlo desde un script de shell o usarlo como un lenguaje stand-alone para scripting.
¿Por qué elegir AWK sobre Perl? Principalmente, porque AWK es parte de UNIX. Siempre puedes contar con él, mientras que el futuro de Perl está en duda. AWK es más fácil de leer que Perl. Para scripts sencillos de procesamiento de texto, particularmente si es para leer archivos línea a línea y dividir por delimitadores, probablemente AWK es la herramienta correcta para el trabajo.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 |
#!/usr/bin/awk -f # Los comentarios tienen este aspecto. # Los programas AWK son una colección de patrones y acciones. El patrón más # importante es BEGIN. Las acciones van en bloques delimitados por llaves. BEGIN { # BEGIN correrá al inicio del programa. Es donde pones todo el código # preliminar antes de procesar los archivos de texto. Si no tienes archivos # de texto, piensa en BEGIN como el punto de entrada principal del script. # Las variables son globales. Asígnalas o úsalas sin declararlas. count = 0 # Los operadores son justo como en C (y amigos). a = count + 1 b = count - 1 c = count * 1 d = count / 1 e = count % 1 # módulo f = count ^ 1 # exponenciación a += 1 b -= 1 c *= 1 d /= 1 e %= 1 f ^= 1 # Incremento y decremento en uno a++ b-- # Como un operador prefijo, regresa el valor modificado ++a --b # Nota que no hay puntación para terminar las instrucciones # Instrucciones de control if (count == 0) print "Iniciando count en 0" else print "Eh?" # O puedes usar el operador ternario print (count == 0) ? "Iniciando count en 0" : "Eh?" # Bloques formados por múltiples líneas usan llaves while (a < 10) { print "La concatenación de strings se hace " " con series " print " de" " strings separados por espacios" print a a++ } for (i = 0; i < 10; i++) print "El viejo confiable ciclo for" # Los operaciones de comparación son estándar... a < b # Menor que a <= b # Menor o igual que a != b # No igual a == b # Igual a > b # Mayor que a >= b # Mayor o igual que # ...así como los operadores lógicos a && b # AND a || b # OR # Además están las expresiones regulares if ("foo" ~ "^fo+$") print "Fooey!" if ("boo" !~ "^fo+$") print "Boo!" # Arrays arr[0] = "foo" arr[1] = "bar" # Desafortunadamente no hay otra manera de inicializar un array. # Tienes que inicializar cada posición del array. # También hay arrays asociativos assoc["foo"] = "bar" assoc["bar"] = "baz" # Y arrays multidimensionales con limitaciones que no mencionaré aquí multidim[0,0] = "foo" multidim[0,1] = "bar" multidim[1,0] = "baz" multidim[1,1] = "boo" # Puedes probar pertenencia a un array if ("foo" in assoc) print "Fooey!" # También puedes usar el operador 'in' para iterar las claves de un array for (key in assoc) print assoc[key] # La terminal es un array especial llamado ARGV for (argnum in ARGV) print ARGV[argnum] # Puedes eliminar elementos de un array. # Esto es útil para prevenir que AWK suponga que algunos argumentos # son archivos por procesar. delete ARGV[1] # El número de argumentos de la terminal está en la variable ARGC print ARGC # AWK tiene tres categorías de funciones incluidas. # Demostraré esas funciones posteriormente. return_value = arithmetic_functions(a, b, c) string_functions() io_functions() } # Así se define una función function arithmetic_functions(a, b, c, localvar) { # Probablemente la parte más molesta de AWK es que no hay variables locales # Todo es global. No es problema en scripts pequeños, pero sí para # scripts más grandes. # Hay un work-around (mmm... hack). Los argumentos de las funciones son # locales para la función, y AWK permite definir más argumentos de función # de los que necesita, por lo que define las variables locales en la # declaración como en la función de arriba. Como convención, agrega # espacios en blanco para distinguir los parámetros de la función de las # variables locales. En este ejemplo, a, b y c son parámetros y localvar es una # variable local. # Ahora, a demostrar las funciones aritméticas # La mayoría de las implementaciones de AWK tienen funciones # trigonométricas estándar localvar = sin(a) localvar = cos(a) localvar = atan2(b, a) # arcotangente de b / a # Y cosas logarítmicas localvar = exp(a) localvar = log(a) # Raíz cuadrada localvar = sqrt(a) # Trucar un flotante a entero localvar = int(5.34) # localvar => 5 # Números aleatorios srand() # La semilla es el argumento. Por defecto usa el tiempo del sistema localvar = rand() # Número aleatorio entre 0 y 1. # Y aquí se regresa el valor return localvar } function string_functions( localvar, arr) { # AWK tiene algunas funciones para procesamiento de strings, # y muchas dependen fuertemente en expresiones regulares. # Buscar y remplazar, primer instancia (sub) o todas las instancias (gsub) # Ambas regresan el número de matches remplazados. localvar = "fooooobar" sub("fo+", "Meet me at the ", localvar) # localvar => "Meet me at the bar" gsub("e", ".", localvar) # localvar => "m..t m. at th. bar" # Buscar una cadena que haga match con una expresión regular # index() hace lo mismo, pero no permite expresiones regulares match(localvar, "t") # => 4, dado que 't' es el cuarto caracter # Separar con base en un delimitador split("foo-bar-baz", arr, "-") # a => ["foo", "bar", "baz"] # Otras funciones útiles sprintf("%s %d %d %d", "Testing", 1, 2, 3) # => "Testing 1 2 3" substr("foobar", 2, 3) # => "oob" substr("foobar", 4) # => "bar" length("foo") # => 3 tolower("FOO") # => "foo" toupper("foo") # => "FOO" } function io_functions( localvar) { # Ya has visto print print "Hello world" # También hay printf printf("%s %d %d %d\n", "Testing", 1, 2, 3) # AWK no tiene handles de archivos en sí mismo. Automáticamente abrirá un # handle de archivo cuando use algo que necesite uno. El string que usaste # para esto puede ser tratada como un handle de archivo para propósitos de I/O. # Esto lo hace similar al scripting de shell: print "foobar" >"/tmp/foobar.txt" # Ahora el string "/tmp/foobar.txt" es un handle. Puedes cerrarlo: close("/tmp/foobar.txt") # Aquí está como correr algo en el shell system("echo foobar") # => muestra foobar # Lee una línea de la entrada estándar (stdin) y lo guarda en localvar getline localvar # Lee una línea desde un pipe "echo foobar" | getline localvar # localvar => "foobar" close("echo foobar") # Lee una línea desde un archivo y la guarda en localvar getline localvar <"/tmp/foobar.txt" close("/tmp/foobar.txt") } # Como dije al inicio, los programas en AWK son una colección de patrones y # acciones. Ya conociste el patrón BEGIN. otros patrones sólo se usan si estás # procesando líneas desde archivos o stdin. # Cuando pasas argumentos a AWK, son tratados como nombres de archivos a # procesar. Los va a procesar todos, en orden. Imagínalos como un ciclo for # implícito, iterando sobre las líneas de estos archivos. Estos patrones y # acciones son como instrucciones switch dentro del ciclo. /^fo+bar$/ { # Esta acción se ejecutará por cada línea que haga match con la expresión # regular /^fo+bar$/, y será saltada por cualquier línea que no haga match. # Vamos a sólo mostrar la línea: print # ¡Wow, sin argumento! Eso es porque print tiene uno por defecto: $0. # $0 es el nombre de la línea actual que se está procesando. # Se crea automáticamente para ti. # Probablemente puedas adivinar que hay otras variables $. Cada línea es # separada implícitamente antes de que se llame cada acción, justo como lo # hace shell. Y, como shell, cada campo puede ser accesado con $. # Esto mostrará el segundo y cuarto campos de la línea print $2, $4 # AWK automáticamente define muchas otras variables que te ayudan a # inspeccionar y procesar cada línea. La más importante es NF # Imprime el número de campos de esta línea print NF # Imprime el último campo de esta línea print $NF } # Cada patrón es realmente un prueba de verdadero/falso. La expresión regular # en el último patrón también es una prueba verdadero/falso, pero parte de eso # estaba oculto. Si no le das un string a la prueba, supondrá $0, la línea que # se está procesando. La versión completa de esto es: $0 ~ /^fo+bar$/ { print "Equivalente al último patrón" } a > 0 { # Esto se ejecutará una vez por línea, mientras a sea positivo } # Y ya te das una idea. Procesar archivos de texto, leyendo una línea a la vez, # y haciendo algo con ella, particularmente separando en un deliminator, es tan # común en UNIX que AWK es un lenguaje de scripting que hace todo eso por ti # sin que tengas que pedirlo. Basta con escribir los patrones y acciones # basados en lo que esperas de la entrada y lo quieras quieras hacer con ella. # Aquí está un ejemplo de un script simple, para lo que AWK es perfecto. # El script lee un nombre de stdin y muestra el promedio de edad para todos los # que tengan ese nombre. Digamos que como argumento pasamos el nombre de un # archivo con este contenido: # # Bob Jones 32 # Jane Doe 22 # Steve Stevens 83 # Bob Smith 29 # Bob Barker 72 # # Éste es el script: BEGIN { # Primero, pedir al usuario el nombre print "¿Para qué nombre quieres el promedio de edad?" # Recuperar una línea de stdin, no de archivos en la línea de comandos getline name <"/dev/stdin" } # Ahora, hacer match con cada línea cuyo primer campo es el nombre dado $1 == name { # Aquí dentro tenemos acceso a variables útiles precargadas: # $0 es toda la línea # $3 es el tercer campo, la edad, que es lo que nos interesa # NF es el número de campos, que debe ser 3 # NR es el número de registros (líneas) vistos hasta ahora # FILENAME es el nombre del archivo que está siendo procesado # FS es el campo separador, " " en este caso # Y muchas más que puedes conocer ejecutando 'man awk' en la terminal. # Llevar el registro de la suma y cuantas líneas han hecho match. sum += $3 nlines++ } # Otro patrón especial es END. Va a ejecutarse después de procesar todos los # archivos de texto. A diferencia de BEGIN, sólo se ejecuta si le das dado una # entrada a procesar. Se ejecutará después de que todos los archivos hayan sido # leídos y procesados según las reglas y acciones que programaste. El propósito # es usualmente para mostrar un reporte final, o hacer algo con el agregado de # los datos que has acumulado durante la ejecución del script. END { if (nlines) print "La edad promedio para " name " es " sum / nlines } |