1 |
chiguire 08/01/09 14:35:58 |
2 |
|
3 |
Added: l-awk1.xml |
4 |
Log: |
5 |
first spanish translation, example issue resolved (thx jesus guerrero) |
6 |
|
7 |
Revision Changes Path |
8 |
1.1 xml/htdocs/doc/es/articles/l-awk1.xml |
9 |
|
10 |
file : http://sources.gentoo.org/viewcvs.py/gentoo/xml/htdocs/doc/es/articles/l-awk1.xml?rev=1.1&view=markup |
11 |
plain: http://sources.gentoo.org/viewcvs.py/gentoo/xml/htdocs/doc/es/articles/l-awk1.xml?rev=1.1&content-type=text/plain |
12 |
|
13 |
Index: l-awk1.xml |
14 |
=================================================================== |
15 |
<?xml version='1.0' encoding="UTF-8"?> |
16 |
<!-- $Header: /var/cvsroot/gentoo/xml/htdocs/doc/es/articles/l-awk1.xml,v 1.1 2008/01/09 14:35:57 chiguire Exp $ --> |
17 |
<!DOCTYPE guide SYSTEM "/dtd/guide.dtd"> |
18 |
|
19 |
<guide link="/doc/en/articles/l-awk1.xml" lang="es" disclaimer="articles"> |
20 |
<title>Awk mediante ejemplos, Parte 1</title> |
21 |
|
22 |
<author title="Author"> |
23 |
<mail link="drobbins@g.o">Daniel Robbins</mail> |
24 |
</author> |
25 |
<author title="Traductor"> |
26 |
<mail link="i92guboj@×××××.es">Jesús Guerrero</mail> |
27 |
</author> |
28 |
|
29 |
<abstract> |
30 |
Awk es un lenguaje muy elegante con un nombre un tanto extraño. En |
31 |
este primer artículo de una seria de tres, Daniel Robbins pondrá en |
32 |
forma tus habilidades de programación con awk. Conforme avance la |
33 |
serie, serán tratados temas un poco más avanzados, culminando en una |
34 |
demostración de aplicación real avanzada escrita usando awk. |
35 |
</abstract> |
36 |
|
37 |
<!-- The original version of this article was published on IBM |
38 |
developerWorks, and is property of Westtech Information |
39 |
Services. This document is an updated version of the original |
40 |
article, and contains various improvements made by the Gentoo |
41 |
Linux Documentation team --> |
42 |
|
43 |
<version>1.4</version> |
44 |
<date>2008-01-08</date> |
45 |
|
46 |
<chapter> |
47 |
<title>Introducción al gran lenguaje de nombre extraño</title> |
48 |
<section> |
49 |
<title>En defensa de awk</title> |
50 |
<body> |
51 |
|
52 |
<p> |
53 |
En esta serie de artículos, te transformaré en un programador |
54 |
productivo con awk. Admito que awk no tiene un nombre particularmente |
55 |
bonito, y que la versión GNU de awk, llamada gawk, suena simplemente |
56 |
rara. Los que no estén familiarizados con el lenguage, al oír "awk" |
57 |
podrían pensar en un código desordenado y anticuado que sería capaz de |
58 |
volver loco al más avispado de los gurús de UNIX (haciéndole gritar |
59 |
repetidamente "kill -s9!" mientras corre hacia la máquina de café). |
60 |
</p> |
61 |
|
62 |
<p> |
63 |
Awk no tiene un gran nombre. Pero es un gran lenguage. Awk está |
64 |
enfocado al procesamiento de texto y la generación de reportes, pero |
65 |
también posee muchas características que permiten la programación |
66 |
seria. Y, al contrario que otros lenguages, la sintaxis de awk es |
67 |
bastante familiar y toma prestados algunos de los mejores elementos de |
68 |
lenguajes como C, python y bash (aunque técnicamente, awk fue creado |
69 |
antes que python y bash. Awk es uno de estos lenguajes que, una vez |
70 |
aprendido se convierte en una parte imprescindible de nuestro arsenal |
71 |
de codificación. |
72 |
</p> |
73 |
</body> |
74 |
</section> |
75 |
|
76 |
<section> |
77 |
<title>El primer awk</title> |
78 |
<body> |
79 |
|
80 |
<pre caption="El primer awk"> |
81 |
$ <i>awk '{ print }' /etc/passwd</i> |
82 |
</pre> |
83 |
|
84 |
<p> |
85 |
Deberías ver el contenido de tu archivo <path>/etc/passwd</path> |
86 |
aparecer ante tus ojos. Ahora explicaré lo que awk ha hecho. Cuando lo |
87 |
hemos llamado, hemos especificado <path>/etc/passwd</path> como |
88 |
nuestro fichero de entrada. Al ejecutar awk, éste ha evaluado el |
89 |
comando para cada línea de <path>/etc/passwd</path>, por orden. Toda |
90 |
la salida se manda a stdout, y así obtenemos una salida idéntica a la |
91 |
que nos daría el comando <c>cat</c> sobre el fichero |
92 |
<path>/etc/pass</path>. |
93 |
</p> |
94 |
|
95 |
<p> |
96 |
Y ahora, una explicación sobre el bloque de código { print }. En awk, |
97 |
las llaves se usan para englobar bloques de código, de forma similar a |
98 |
C. Dentro de nuestro bloque de código, tenemos un solo comando |
99 |
print. En awk, cuando un comando print aparece solo, se imprime todo |
100 |
el contenido de la línea. |
101 |
</p> |
102 |
|
103 |
<pre caption="Imprimiendo la línea actual"> |
104 |
$ <i>awk '{ print $0 }' /etc/passwd</i> |
105 |
$ <i>awk '{ print "" }' /etc/passwd</i> |
106 |
</pre> |
107 |
|
108 |
<p> |
109 |
En awk, la variable $0 representa la línea actual, por tanto, print y |
110 |
print $0 hacen exactamente lo mismo. |
111 |
</p> |
112 |
|
113 |
<pre caption="Llenar la pantalla con un texto"> |
114 |
$ <i>awk '{ print "hiya" }' /etc/passwd</i> |
115 |
</pre> |
116 |
</body> |
117 |
</section> |
118 |
|
119 |
<section> |
120 |
<title>Múltiples campos</title> |
121 |
<body> |
122 |
|
123 |
<pre caption="print $1"> |
124 |
$ <i>awk -F":" '{ print $1 $3 }' /etc/passwd</i> |
125 |
halt7 |
126 |
operator11 |
127 |
root0 |
128 |
shutdown6 |
129 |
sync5 |
130 |
bin1 |
131 |
<comment>....etc.</comment> |
132 |
</pre> |
133 |
|
134 |
<pre caption="print $1 $3"> |
135 |
$ <i>awk -F":" '{ print $1 " " $3 }' /etc/passwd</i> |
136 |
</pre> |
137 |
|
138 |
<pre caption="$1$3"> |
139 |
$ <i>awk -F":" '{ print "username: " $1 "\t\tuid:" $3 }' /etc/passwd</i> |
140 |
username: halt uid:7 |
141 |
username: operator uid:11 |
142 |
username: root uid:0 |
143 |
username: shutdown uid:6 |
144 |
username: sync uid:5 |
145 |
username: bin uid:1 |
146 |
<comment>... etc.</comment> |
147 |
</pre> |
148 |
</body> |
149 |
</section> |
150 |
|
151 |
<section> |
152 |
<title>Guiónes externos</title> |
153 |
<body> |
154 |
|
155 |
<pre caption="Guión de ejemplo"> |
156 |
BEGIN { FS=":" } |
157 |
{ print $1 } |
158 |
</pre> |
159 |
|
160 |
<p> |
161 |
La diferencia entre estos dos métodos consiste en cómo establecemos el |
162 |
separador de campo. En este guión, el separador es especificado en el |
163 |
mísmo código (estableciendo la variable FS). Mientras que en nuestro |
164 |
anterior ejemplo, FS se establece a través de la opción -F":". Por |
165 |
norma general es mejor establecerlo dentro del mismo script, |
166 |
simplemente porque será un argumento menos que tendrás que tendrás que |
167 |
recordar teclear. Cubriremos la variable FS en más detalle más tarde |
168 |
en este mismo artículo. |
169 |
</p> |
170 |
</body> |
171 |
</section> |
172 |
|
173 |
<section> |
174 |
<title>The BEGIN and END blocks</title> |
175 |
<body> |
176 |
|
177 |
<p> |
178 |
Normalmente, awk ejecuta cada bloque de código del guión una vez por |
179 |
cada línea de entrada que se le proporcione. Sin embargo, hay muchas |
180 |
situaciones donde se necesita ejecutar un código de inicialización |
181 |
antes de que awk comience a procesar el texto del fichero de |
182 |
entrada. Para dichas situaciones, awk permite definir un bloque |
183 |
BEGIN. Hemos usado un bloque BEGIN en el ejemplo anterior. Como el |
184 |
bloque BEGIN es evaluado antes de que awk procese el fichero de |
185 |
entrada, es un lugar excelente para inicializar la variable FS |
186 |
(separador de campo), imprimir una cabecera o inicializar otras |
187 |
variables globales a las que podrás hacer referencia más adelante en |
188 |
el programa. |
189 |
</p> |
190 |
|
191 |
<p> |
192 |
Awk también provee otro bloque especial, llamado el bloque END. Awk |
193 |
ejecuta este bloque tras procesar todas las líneas del fichero de |
194 |
entrada. Típicamente, el bloque END se usa para realizar cálculos |
195 |
finales o imprimir sumarios que deban aparecer al final del flujo de |
196 |
salida. |
197 |
</p> |
198 |
</body> |
199 |
</section> |
200 |
|
201 |
<section> |
202 |
<title>Expresiones regulares y bloques</title> |
203 |
<body> |
204 |
|
205 |
<pre caption="Regular expressions and blocks"> |
206 |
/foo/ { print } |
207 |
/[0-9]+\.[0-9]*/ { print } |
208 |
</pre> |
209 |
</body> |
210 |
</section> |
211 |
|
212 |
<section> |
213 |
<title>Expresiones y bloques</title> |
214 |
<body> |
215 |
|
216 |
<pre caption="fredprint"> |
217 |
$1 == "fred" { print $3 } |
218 |
</pre> |
219 |
|
220 |
<pre caption="root"> |
221 |
$5 ~ /root/ { print $3 } |
222 |
</pre> |
223 |
</body> |
224 |
</section> |
225 |
|
226 |
<section> |
227 |
<title>Sentencias condicionales</title> |
228 |
<body> |
229 |
|
230 |
<pre caption="if"> |
231 |
{ |
232 |
if ( $5 ~ /root/ ) { |
233 |
print $3 |
234 |
} |
235 |
} |
236 |
</pre> |
237 |
|
238 |
<p> |
239 |
Ambos scripts funcionan de forma idéntica. En el primer ejemplo, la |
240 |
expresión booleana se pone fuera del bloque, mientras que en el |
241 |
segundo, el bloque se ejecuta para cada línea, y la impresión se |
242 |
realiza de forma selectiva usando una sentencia if. Ambos métodos son |
243 |
válidos, y puedes escoger el que mejor se adapte a tu guión. |
244 |
</p> |
245 |
|
246 |
<pre caption="if if"> |
247 |
{ |
248 |
if ( $1 == "foo" ) { |
249 |
if ( $2 == "foo" ) { |
250 |
print "uno" |
251 |
} else { |
252 |
print "one" |
253 |
} |
254 |
} else if ($1 == "bar" ) { |
255 |
print "two" |
256 |
} else { |
257 |
print "three" |
258 |
} |
259 |
} |
260 |
</pre> |
261 |
|
262 |
<pre caption="if"> |
263 |
! /matchme/ { print $1 $3 $4 } |
264 |
</pre> |
265 |
|
266 |
<pre caption="if"> |
267 |
{ |
268 |
if ( $0 !~ /matchme/ ) { |
269 |
print $1 $3 $4 |
270 |
} |
271 |
} |
272 |
</pre> |
273 |
|
274 |
<p> |
275 |
Ambos scripts imprimirán solo aquellas líneas que no contengan una |
276 |
cadena de caracteres matchme. De nuevo, puedes escoger el que mejor se |
277 |
ajuste a tu código. Ambos hacen lo mismo. |
278 |
</p> |
279 |
|
280 |
<pre caption="Imprimiendo los campos iguales a foo y bar"> |
281 |
( $1 == "foo" ) && ( $2 == "bar" ) { print } |
282 |
</pre> |
283 |
|
284 |
<p> |
285 |
Este ejemplo imprimirá solo aquellas líneas en las que el campo 1 sea |
286 |
igual a foo y el campo 2 sea igual a bar. |
287 |
</p> |
288 |
</body> |
289 |
</section> |
290 |
|
291 |
<section> |
292 |
<title>¡Variables numéricas!</title> |
293 |
<body> |
294 |
|
295 |
<p> |
296 |
En el bloque BEGIN, inicializamos nuestra variable entera x a |
297 |
cero. Luego, cada vaz que awk encuentra una línea en blanco, ejecutará |
298 |
la sentencia x=x+1, incrementando x. Tras ser procesadas todas las |
299 |
líneas, el bloque END se ejecutará, y awk imprimirá un sumario final |
300 |
especificando el número total de líneas en blanco que ha encontrado. |
301 |
</p> |
302 |
</body> |
303 |
</section> |
304 |
|
305 |
<section> |
306 |
<title>Variables no interpretables como numéricas</title> |
307 |
<body> |
308 |
|
309 |
<pre caption="Campo ejemplo"> |
310 |
2.01 |
311 |
</pre> |
312 |
|
313 |
<pre caption="1.01x$( )1.01"> |
314 |
{ print ($1^2)+1 } |
315 |
</pre> |
316 |
|
317 |
<p> |
318 |
Si experimentas un poco, encontrarás que si una variable no contiene |
319 |
un número válido, awk tratará dicha variable numéricamente como un |
320 |
cero si es evaluada en alguna expresión matemática. |
321 |
</p> |
322 |
</body> |
323 |
</section> |
324 |
|
325 |
<section> |
326 |
<title>Montones de operadores</title> |
327 |
<body> |
328 |
|
329 |
<p> |
330 |
Otra cosa buena de awk es su gran cantidad complementaria de |
331 |
operadores matemáticos. Además de la suma, la resta, la multiplicación |
332 |
y la división, awk nos permite usar el operador de exponenciación "^", |
333 |
el operador módulo (restos) "%" y y un surtido de operadores de |
334 |
asignación que ha tomado prestados de C. |
335 |
</p> |
336 |
|
337 |
<p> |
338 |
Estos incluyen pre- y post-incremento/decremento ( i++, --foo ) y |
339 |
operadores de asignación combinados con suma, resta, multiplicación o |
340 |
división ( a+=3, b*=2, c/=2.2, d-=6.2 ). Pero eso no es todo -- |
341 |
también podemos usar útiles operadores de asignación combinados con |
342 |
operaciones de modulo o exponenciación ( a^=2, b%=4 ). |
343 |
</p> |
344 |
</body> |
345 |
</section> |
346 |
|
347 |
<section> |
348 |
<title>Separadores de campo</title> |
349 |
<body> |
350 |
|
351 |
<p> |
352 |
Awk tienes su propio surtido de variables especiales. Algunas nos |
353 |
permiten afinar el comportamiento de awk, mientras otras pueden ser |
354 |
leídas para obtener imformación valiosa sobre la entrada. Ya hemos |
355 |
usado una de estas variables especiales: FS. Como se mención antes, |
356 |
ésta nos permite especificar la secuencia de caracteres que awk espera |
357 |
encontrar como separador de campo. Cuando usamos |
358 |
<path>/etc/passwd</path> como entrada, FS se fijó a ":". Si bien esto |
359 |
funcionó en ese momento, FS nos permite mucha más flexibilidad. |
360 |
</p> |
361 |
|
362 |
<pre caption="Otro separador de campo"> |
363 |
FS="\t+" |
364 |
</pre> |
365 |
|
366 |
<p> |
367 |
Arriba usando el operador especial de expresiones regulares "+", que |
368 |
significa "una ocurrencia o más del caracter anterior". |
369 |
</p> |
370 |
|
371 |
<pre caption="Fijando FS como espacio en blanco"> |
372 |
FS="[[:space:]+]" |
373 |
</pre> |
374 |
|
375 |
<p> |
376 |
Si bien esta asignación funcionará, no es necesaria. ¿Por qué? Porque |
377 |
por defecto, FS está prefijado como un solo espacio en blanco, que awk |
378 |
interpreta como "uno o más espacios o tabuladores". En este ejemplo en |
379 |
particular, ¡el valor predeterminado de FS era exáctamente lo que |
380 |
andabas buscando desde primera hora! |
381 |
</p> |
382 |
|
383 |
<pre caption="Ejemplo de separador de campo"> |
384 |
FS="foo[0-9][0-9][0-9]" |
385 |
</pre> |
386 |
</body> |
387 |
</section> |
388 |
|
389 |
<section> |
390 |
<title>Número de campos</title> |
391 |
<body> |
392 |
|
393 |
<pre caption="Número de campos"> |
394 |
{ |
395 |
if ( NF > 2 ) { |
396 |
print $1 " " $2 ":" $3 |
397 |
} |
398 |
} |
399 |
</pre> |
400 |
</body> |
401 |
</section> |
402 |
|
403 |
<section> |
404 |
<title>Número de registro</title> |
405 |
<body> |
406 |
|
407 |
<pre caption="Número de registro"> |
408 |
{ |
409 |
<comment>#saltar cabecera</comment> |
410 |
if ( NR > 10 ) { |
411 |
print "ok, ¡ahora a por la información!" |
412 |
} |
413 |
} |
414 |
</pre> |
415 |
|
416 |
<p> |
417 |
Awk provee variables adicionales que pueden ser usadas para varios |
418 |
propósitos. Veremos más de estas variables en artículos posteriores. |
419 |
</p> |
420 |
|
421 |
<p> |
422 |
Hemos llegado al final de nuestra exploración inicial de awk. Conforme |
423 |
la serie avance, demostraré funcionalidades más avanzadas de awk, y |
424 |
terminaremos la serie con una aplicación real en awk. Mientras tanto, |
425 |
si quieres aprender más, examina la lista de recursos listada más |
426 |
abajo. |
427 |
</p> |
428 |
</body> |
429 |
</section> |
430 |
</chapter> |
431 |
|
432 |
<chapter> |
433 |
<title>Recursos</title> |
434 |
<section> |
435 |
<title>Enlaces útiles</title> |
436 |
<body> |
437 |
|
438 |
<ul> |
439 |
<li> |
440 |
Lee otros artículos de Daniel sobre awk publicados en |
441 |
developerWorks: Awk mediante ejemplos, <uri |
442 |
link="l-awk2.xml">Parte 2</uri> y <uri link="l-awk3.xml">Parte |
443 |
3</uri>. |
444 |
</li> |
445 |
<li> |
446 |
Si prefieres un buen libro a la vieja usanza, el <uri |
447 |
link="http://www.oreilly.com/catalog/sed2/">sed & awk, 2ª |
448 |
Edición</uri> de O'Reilly es una buena opción. |
449 |
</li> |
450 |
<li> |
451 |
Asegúrate también de examinar <uri |
452 |
link="http://www.faqs.org/faqs/computer-lang/awk/faq/">comp.lang.awk |
453 |
FAQ</uri>. También contiene varios enlaces sobre awk. |
454 |
</li> |
455 |
<li> |
456 |
El <uri link="http://sparky.rice.edu/~hartigan/awk.html">tutorial |
457 |
de awk</uri> de Patrick Hartigan viene con varios scripts |
458 |
interesantes de awk. |
459 |
</li> |
460 |
<li> |
461 |
El <uri link="http://www.tasoft.com/tawk.html">Compilador TAWK de |
462 |
Thompson</uri> compila guiones de awk transformándolos en binarios |
463 |
ejecutables. Hay versiones para Widows, OS/2, DOS, y UNIX. |
464 |
</li> |
465 |
<li> |
466 |
<uri link="http://www.gnu.org/software/gawk/manual/gawk.html">La |
467 |
guía de usuario de GNU Awk</uri> también está disponible para |
468 |
referencia en línea. |
469 |
</li> |
470 |
</ul> |
471 |
</body> |
472 |
</section> |
473 |
</chapter> |
474 |
</guide> |
475 |
|
476 |
|
477 |
|
478 |
-- |
479 |
gentoo-commits@l.g.o mailing list |