summaryrefslogtreecommitdiffhomepage
path: root/es-es/awk-es.html.markdown
diff options
context:
space:
mode:
Diffstat (limited to 'es-es/awk-es.html.markdown')
-rw-r--r--es-es/awk-es.html.markdown362
1 files changed, 362 insertions, 0 deletions
diff --git a/es-es/awk-es.html.markdown b/es-es/awk-es.html.markdown
new file mode 100644
index 00000000..307ba817
--- /dev/null
+++ b/es-es/awk-es.html.markdown
@@ -0,0 +1,362 @@
+---
+language: awk
+filename: learnawk-es.awk
+contributors:
+ - ["Marshall Mason", "http://github.com/marshallmason"]
+translators:
+ - ["Hugo Guillén-Ramírez", "http://github.com/HugoGuillen"]
+lang: es-es
+---
+
+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.
+
+```awk
+#!/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(a, b) # 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
+}
+
+```
+Más información:
+
+* [Tutorial de AWK](http://www.grymoire.com/Unix/Awk.html)
+* [Página man de AWK](https://linux.die.net/man/1/awk)
+* [La guía del usuario de GNU Awk](https://www.gnu.org/software/gawk/manual/gawk.html): GNU Awk se encuentra en la mayoría de los sistemas Linux.