Gentoo Archives: gentoo-commits

From: "Jose Luis Rivero (yoswink)" <yoswink@g.o>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] gentoo commit in xml/htdocs/doc/es/articles: l-sed1.xml l-sed2.xml l-sed3.xml
Date: Fri, 02 Nov 2007 14:42:40
Message-Id: E1Inxif-0007FZ-Gk@stork.gentoo.org
1 yoswink 07/11/02 14:41:57
2
3 Added: l-sed1.xml l-sed2.xml l-sed3.xml
4 Log:
5 New translation
6
7 Revision Changes Path
8 1.1 xml/htdocs/doc/es/articles/l-sed1.xml
9
10 file : http://sources.gentoo.org/viewcvs.py/gentoo/xml/htdocs/doc/es/articles/l-sed1.xml?rev=1.1&view=markup
11 plain: http://sources.gentoo.org/viewcvs.py/gentoo/xml/htdocs/doc/es/articles/l-sed1.xml?rev=1.1&content-type=text/plain
12
13 Index: l-sed1.xml
14 ===================================================================
15 <?xml version='1.0' encoding="UTF-8"?>
16 <!-- $Header: /var/cvsroot/gentoo/xml/htdocs/doc/es/articles/l-sed1.xml,v 1.1 2007/11/02 14:41:56 yoswink Exp $ -->
17 <!DOCTYPE guide SYSTEM "/dtd/guide.dtd">
18
19 <guide link="/doc/es/articles/l-sed1.xml" disclaimer="articles" lang="es">
20 <title>Sed mediante ejemplos, Parte 1</title>
21
22 <author title="Autor">
23 <mail link="drobbins@g.o">Daniel Robbins</mail>
24 </author>
25 <author title="Traductor">
26 <mail link="LinuxBlues@×××××××××.org">LinuxBlues</mail>
27 </author>
28
29 <abstract>
30 En esta serie de artículos, Daniel Robbins mostrará cómo usar el poderoso
31 (aunque muy a menudo olvidado) editor de flujo UNIX, sed. Sed es una
32 herramienta ideal para editar archivos por lotes o para crear macros en el
33 intérprete de comandos que modifiquen archivos existentes de forma muy
34 poderosa.
35 </abstract>
36
37 <!-- The original version of this article was published on IBM developerWorks,
38 and is property of Westtech Information Services. This document is an updated
39 version of the original article, and contains various improvements made by the
40 Gentoo Linux Documentation team -->
41
42 <version>1.4</version>
43 <date>2005-10-09</date>
44
45 <chapter>
46 <title>Dar a conocer el poderoso editor UNIX</title>
47 <section>
48 <title>Elegir un editor</title>
49 <body>
50
51 <p>
52 En el mundo UNIX, disponemos de muchas opciones cuando necesitamos editar
53 archivos. Pensando en ello -- vienen a la mente vi, emacs y jed, así como
54 muchos otros. Todos nosotros tenemos nuestro editor favorito (así como nuestras
55 combinaciones de teclas favoritas) que hemos llegado a conocer y ahora amamos.
56 Con nuestro editor de confianza, estamos listos para manejar cualquier tarea de
57 administración relacionada con UNIX o de programación con facilidad.
58 </p>
59
60 <p>
61 Mientras que los editores interactivos son buenos, tienen algunas limitaciones.
62 A pesar de que su naturaleza interactiva puede ser un punto fuerte, también
63 puede ser una debilidad. Consideremos una situación en la que necesitemos hacer
64 un tipo muy similar de cambios en un grupo de archivos. Podemos lanzar nuestro
65 editor de textos favorito y realizar una labor mundana, tediosa y repetitiva,
66 malgastando nuestro tiempo en muchas ediciones a mano. Pero hay una forma mejor
67 de hacerlo
68 </p>
69
70 </body>
71 </section>
72 <section>
73 <title>Introducción a sed</title>
74 <body>
75
76 <p>
77 Sería bueno poder automatizar el proceso de editar archivos, de forma que
78 podamos "procesar por lotes" la edición de archivos, e incluso crear macros con
79 la habilidad de realizar cambios sofisticados a archivos existentes.
80 Afortunadamente para nosotros y para este tipo de situaciones, hay un método
81 mucho mejor -- y este método se denomina sed.
82 </p>
83
84 <p>
85 sed es un ligero editor de flujo que está incluido en casi todos los
86 sabores UNIX, Linux incluido. sed tiene muchas buenas características. La
87 primera de ellas es que es de peso muy ligero, normalmente muy inferior al de
88 nuestro lenguaje favorito de macros. En segundo lugar, dado que sed es un
89 editor de flijo, puede editar los datos que recibe de stdin, como aquellos
90 redireccionados. Por lo que no se necesita tener los datos a editar almacenados
91 en un archivo del disco. Dado que los datos pueden redirigirse a sed, es muy
92 fácil usar sed como parte de un largo y complejo redireccionamiento en un
93 archivo por lotes de nuestro intérprete de comandos. Intentemos hacerlo con
94 nuestro editor favorito.
95 </p>
96
97 </body>
98 </section>
99 <section>
100 <title>sed GNU</title>
101 <body>
102
103 <p>
104 Afortunadamente para nosotros, usuarios de Linux, una de las mejores versiones
105 disponibles de sed es la versión de GNU, actualmente en su versión 3.02. Cada
106 distribución de Linux posee el editor sed de GNU o, al menos, debería. El sed
107 de GNU es muy conocido, no únicamente porque su código fuente sea de libre
108 distribución, sino porque tiene muchas extensiones del estándar POSIX de sed
109 que nos evitarán desperdiciar el tiempo. El sed de GNU tampoco sufre muchas de
110 las limitaciones del sed anterior y propietario, como una longitud de línea
111 limitada -- El sed de GNU puede manejar líneas de cualquier tamaño con
112 facilidad.
113 </p>
114
115 </body>
116 </section>
117 <section>
118 <title>El último sed de GNU</title>
119 <body>
120
121 <p>
122 Mientras elaboraba este artículo, noté que varios aficionados de sed hacían
123 referencia al sed de GNU 3.02a. A pesar de que no pude encontrarlo en
124 <uri>ftp://ftp.gnu.org</uri> (ver los <uri link="#recursos">Recursos</uri>
125 para encontrar estos enlaces), por lo que tuve que buscarlo en otra parte. Lo
126 encontré en <uri>ftp://alpha.gnu.org</uri>, bajo <path>/pub/sed</path>. Lo
127 descargué, compilé e instalé para observar, pasados unos minutos, que la última
128 versión de sed es la 3.02.80 -- y puede encontrarse su código fuente justo al
129 lado de las de 3.02a, en <uri>ftp://alpha.gnu.org</uri>. Después de tener el
130 sed de GNU 3.02.80 instalado, ya estaba listo para continuar.
131 </p>
132
133 </body>
134 </section>
135 <section>
136 <title>El sed correcto</title>
137 <body>
138
139 <p>
140 En esta serie, utilizaré el sed de GNU versión 3.02.80. Algunos (aunque pocos)
141 de los ejemplos más avanzados en mi serie de artículos acerca de sed no
142 funcionarán con el sed de GNU 3.02 ó 3.02a. Si se está usando un sed que no sea
143 el de GNU los resultados pueden variar. ¿Por qué no nos tomamos el tiempo
144 necesario para instalar el sed 3.02.80 de GNU ahora? Después, no sólo estaremos
145 preparados para el resto de los artículos acerca de sed, sino que estaremos
146 usando, indiscutiblemente, el mejor sed que existe.
147 </p>
148
149 </body>
150 </section>
151 <section>
152 <title>Ejemplos con sed</title>
153 <body>
154
155 <p>
156 Sed trabaja realizando cualquier número de operaciones de edición especificadas
157 por el usuario ("comandos") en los datos de entrada. Sed se basa en líneas, por
158 lo que los comandos se realizan en cada línea, siguiendo un orden. Sed, escribe
159 sus resultados en la salida estándar (stdout); por lo que no modifica ninguno
160 de los archivos de entrada.
161 </p>
162
163 <p>
164 Veamos algunos ejemplos. Los primeros van a ser un poco inútiles, debido a que
165 pretendo mostrar con ellos cómo trabaja sed, en lugar de realizar cualquier
166 tarea útil. De cualquier modo, si somos principiantes con sed, es muy
167 importante entenderlos. He aquí nuestro primer ejemplo:
168 </p>
169
170 <pre caption="Ejemplo de uso de sed">
171 $ <i>sed -e 'd' /etc/services</i>
172 </pre>
173
174 <p>
175 Si tecleamos este comando, no obtendremos absolutamente ningún mensaje. ¿Qué ha
176 ocurrido? En este ejemplo, hemos llamado a sed con un comando de edición,
177 <c>d</c>. Sed abrió el archivo <path>/etc/services</path>, leyó una línea en su
178 memoria intermedia, realizó nuestro comando de edición ("borrar una línea") y
179 después mostró su memoria intermedia de patrones (la cual estaba vacía).
180 Después repitió estos pasos para cada línea sucesivamente. Con lo cual no se
181 produjo ningún mensaje, dado que el comando <c>d</c> erradicó todas y cada una
182 de las líneas en la memoria intermedia de patrones.
183 </p>
184
185 <p>
186 Hay un par de cosas a considerar en este ejemplo. La primera,
187 <path>/etc/services</path> no fue modificado en absoluto. Esto se debe a que
188 sed únicamente lee del archivo que se le indica en la línea de comandos,
189 usándolo como entrada -- ni siquiera intenta modificarlo. La segunda es que sed
190 está orientado hacia líneas. El comando <c>d</c> no le dijo a sed que borrara
191 todos los datos sin la más mínima precaución. En su lugar, sed leyó línea por
192 línea /etc/services en su memoria intermedia interna, denominada memoria
193 intermedia de patrones (pattern buffer). Cada vez que se leía una línea en la
194 memoria intermedia de patrones, realizaba el comando <c>d</c> e imprimía los
195 contenidos de la memoria intermedia de patrones (ninguno en este ejemplo).
196 Después mostraré cómo usar rangos de direcciones para controlar las líneas a
197 las que se aplica un comando -- aunque en ausencia de los mismos, un comando se
198 aplica a todas las líneas.
199 </p>
200
201 <p>
202 La tercera cosa a notar es el uso de comillas simples para introducir el
203 comando <c>d</c>. Es una buena idea adquirir el hábito de usar comillas simples
204 para introducir los comandos sed, para deshabilitar la expansión del intérprete
205 de comandos.
206 </p>
207
208 </body>
209 </section>
210 <section>
211 <title>Otro ejemplo de uso de sed</title>
212 <body>
213
214 <p>
215 He aquí un ejemplo de cómo usar sed para eliminar la primera línea del archivo
216 <path>/etc/services</path> de nuestro flujo de salida:
217 </p>
218
219 <pre caption="Otro ejemplo de uso de sed">
220 $ <i>sed -e '1d' /etc/services | more</i>
221 </pre>
222
223 <p>
224 Como puede verse, este comando es muy similar a nuestro primer comando <c>d</c>
225 exceptuando que se encuentra precedido por un <c>1</c>. Si al verlo hemos
226 pensado que el <c>1</c> hacía alusión a la línea 1, estábamos en lo cierto.
227 Mientras que en nuestro primer ejemplo usamos <c>d</c> por sí mismo, en este
228 caso usamos el comando <c>d</c> precedido por una dirección lineal opcional.
229 Usando direcciones, podemos decirle a sed que edite únicamente una línea o sólo
230 unas líneas.
231 </p>
232
233 </body>
234 </section>
235 <section>
236 <title>Rangos de direcciones</title>
237 <body>
238
239 <p>
240 Ahora, veamos cómo especificar rangos de direcciones. En este ejemplo, sed
241 borrará de la línea 1 a la 10 de la salida:
242 </p>
243
244 <pre caption="Especificar un rango de direcciones">
245 $ <i>sed -e '1,10d' /etc/services | more</i>
246 </pre>
247
248 <p>
249 Cuando separamos dos direcciones por una coma, sed aplicará el siguiente
250 comando al rango que empieza con la primera dirección y terminará con la
251 segunda dirección. En este ejemplo, el comando <c>d</c> se ha aplicado desde la
252 línea 1 hasta la línea 10, inclusive. El resto de líneas son ignoradas.
253 </p>
254
255 </body>
256 </section>
257 <section>
258 <title>Direcciones con expresiones regulares</title>
259 <body>
260
261 <p>
262 Ha llegado el momento de un ejemplo mucho más útil. Digamos que queríamos ver
263 los contenidos del archivo <path>/etc/services</path>, pero no estamos
264 interesados en ver ninguno de los comentarios incluidos. Como todos sabemos, se
265 pueden añadir comentarios en nuestro archivo <path>/etc/services</path>
266 comenzando la línea con un carácter '#'. Para evitar los comentarios, le
267 indicamos a sed que elimine todas las líneas que comienzan con '#'. He aquí
268 cómo hacerlo:
269 </p>
270
271 <pre caption="Eliminar las líneas que comienzan con #">
272 $ <i>sed -e '/^#/d' /etc/services | more</i>
273 </pre>
274
275 <p>
276 Intentemos realizar este ejemplo y veamos lo que ocurre. Notaremos que sed
277 realiza la labor solicitada con gran rapidez. Vamos a figurarnos qué es lo que
278 ha ocurrido.
279 </p>
280
281 <p>
282 Para comprender el comando '/^#/d', antes necesitamos diseccionarlo. Primero,
283 eliminemos la 'd' -- estamos usando el mismo comando de borrado de líneas que
284 hemos usado previamente. La nueva parte añadida es la '/^#/', que es un nuevo
285 tipo de dirección mediante una expresión regular. Las direcciones con
286 expresiones regulares se indican siempre entre barras. Especifican un patrón y
287 el comando que está a continuación de una dirección con expresión regular
288 únicamente se aplicará a una línea si encuentra dicho patrón en ella.
289 </p>
290
291 <p>
292 Por lo que '/^#/' es una expresión regular. Pero, ¿qué es lo que hace?
293 Obviamente, este sería un buen momento para repasar las expresiones regulares.
294 </p>
295
296 </body>
297 </section>
298 <section>
299 <title>Repaso a las expresiones regulares</title>
300 <body>
301
302 <p>
303 Podemos usar expresiones regulares para expresar patrones que podemos encontrar
304 en el texto. Si hemos usado alguna vez el carácter '*' en un comando del
305 intérprete de comandos, hemos usado algo muy similar, aunque no idéntico, a las
306 expresiones regulares. Aquí tenemos los caracteres especiales que pueden usarse
307 en las expresiones regulares:
308 </p>
309
310 <table>
311 <tr>
312 <th>Carácter</th>
313 <th>Descripción</th>
314 </tr>
315 <tr>
316 <ti>^</ti>
317 <ti>Apunta al comienzo de la línea</ti>
318 </tr>
319 <tr>
320 <ti>$</ti>
321 <ti>Apunta al final de la línea</ti>
322 </tr>
323 <tr>
324 <ti>.</ti>
325 <ti>Apunta a un único carácter</ti>
326 </tr>
327 <tr>
328 <ti>*</ti>
329 <ti>Apunta a cero o más ocurrencias del carácter previo</ti>
330 </tr>
331 <tr>
332 <ti>[ ]</ti>
333 <ti>Apunta a todos los caracteres entre los corchetes</ti>
334 </tr>
335 </table>
336
337 <p>
338 Veamos algunos ejemplos con expresiones regulares para fascilitar las cosas.
339 Todos estos ejemplos serán aceptados por sed como direcciones válidas que
340 pueden aparecer a la izquierda de cualquier comando:
341 </p>
342
343 <table>
344 <tr>
345 <th>Expresión regular</th>
346 <th>Descripción</th>
347 </tr>
348 <tr>
349 <ti>/./</ti>
350 <ti>Apuntará a cualquier línea que contenga al menos un carácter</ti>
351 </tr>
352 <tr>
353 <ti>/../</ti>
354 <ti>Apuntará a cualquier línea que contenga al menos dos caracteres</ti>
355 </tr>
356 <tr>
357 <ti>/^#/</ti>
358 <ti>Apuntará a cualquier línea que comience con un '#'</ti>
359 </tr>
360 <tr>
361 <ti>/^$/</ti>
362 <ti>Apuntará a cualquier línea en blanco</ti>
363 </tr>
364 <tr>
365 <ti>/}^/</ti>
366 <ti>Apuntará a toda línea que termine con un '}' (sin espacios)</ti>
367 </tr>
368 <tr>
369 <ti>/} *^/</ti>
370 <ti>Apuntará a toda línea que termine con un '}' con cero o más
371 espacios</ti>
372 </tr>
373 <tr>
374 <ti>/[abc]/</ti>
375 <ti>Apuntará a toda línea que contenga una 'a', 'b', o 'c' minúscula</ti>
376 </tr>
377 <tr>
378 <ti>/^[abc]/</ti>
379 <ti>Apuntará a cualquier línea que empiece con 'a', 'b', o 'c'</ti>
380 </tr>
381 </table>
382
383 <p>
384 Recomiendo encarecidamente intentarlo con varios de estos ejemplos. Tomarse el
385 tiempo necesario para familiarizarse con las expresiones regulares, e intentar
386 usar algunas expresiones regulares de nuestra propia invención. Puede usarse
387 una expreg de este modo:
388 </p>
389
390 <pre caption="Forma adecuada de usar expreg">
391 $ <i>sed -e '/expreg/d' /ruta/a/mi/archivo/de/pruebas | more</i>
392 </pre>
393
394 <p>
395 Esto dará lugar a que sed borre cualquier línea coincidente. De todos modos,
396 puede ser más sencillo familiarizarse con las expresiones regulares pidiéndole
397 a sed que muestre las coincidencias con expreg y que borre las que no
398 coincidan, en lugar de seguir el camino opuesto. Lo cual puede lograrse con el
399 siguiente comando:
400 </p>
401
402 <pre caption="Imprimir las coincidencias expreg">
403 $ <i>sed -n -e '/expreg/p' /ruta/a/mi/archivo/de/pruebas | more</i>
404 </pre>
405
406 <p>
407 Hay que tomar nota de la opción '-n', que indica a sed que no imprima el
408 espacio en el patrón a menos que se le indique. También observamos que hemos
409 sustituido el comando <c>d</c> con el comando <c>p</c>, que como se podrá
410 pensar solicita a sed que muestre el espacio entre patrones. Por lo tanto, sólo
411 se mostrarán las expresiones que coincidan.
412 </p>
413
414 </body>
415 </section>
416 <section>
417 <title>Más direcciones</title>
418 <body>
419
420 <p>
421 Hasta ahora, hemos echado un vistazo a direcciones lineales, direcciones en
422 rangos lineales y direcciones expreg. Pero aún hay más posibilidades. Podemos
423 especificar dos expresiones regulares separadas por una coma, y sed marcará
424 todas las líneas que comiencen con la primera expresión regular seleccionada
425 hasta la línea (incluida) que contenga la segunda expresión regular. Por
426 ejemplo, el siguiente comando mostrará un bloque de texto que comience con una
427 línea que contenga "PRINCIPIO", y termine con una línea que contenga "FIN":
428 </p>
429
430 <pre caption="Imprimir el bloque deseado de texto">
431 $ <i>sed -n -e '/PRINCIPIO/,/FIN/p' /mi/archivo/de/pruebas | more</i>
432 </pre>
433
434 <p>
435 Si "PRINCIPIO" no se encuentra, no se imprimirá ningún dato. Y si se encuentra
436 "PRINCIPIO" pero no se encuentra ninguna línea que contenga "FIN" a
437 continuación, todas las líneas siguientes se imprimirán. Esto ocurre debido a
438 la naturaleza basada en flujo de sed -- desconoce si "FIN" aparecerá o no.
439 </p>
440
441 </body>
442 </section>
443 <section>
444 <title>Ejemplo con código fuente en C</title>
445 <body>
446
447 <p>
448 Si únicamente se quiere imprimir la función main() en un archivo de código
449 fuente en C, se podría teclear:
450 </p>
451
452 <pre caption="Imprimir la función main() en un archivo de código fuente en C">
453 $ <i>sed -n -e '/main[[:space:]]*(/,/^}/p' sourcefile.c | more</i>
454 </pre>
455
456 <p>
457 Este comando tiene dos expresiones regulares, '/main[[:space:]]*(/' y '/^}/', y
458 un comando , <c>p</c>. La primera expresión regular apuntará a la cadena "main"
459 seguida de cualquier número de espacios o tabuladores, seguida además por un
460 paréntesis abierto. Lo cual debería coincidir con el comienzo de nuestra
461 declaración main() en ANSI C.
462 </p>
463
464 <p>
465 En este caso de expresión regular, encontramos la clase de caracteres
466 '[[:space:]]'. La cual es únicamente una palabra clave especial para sed que le
467 indica a sed que apunte a cualquier espacio o TAB. De haberlo querido, en lugar
468 de teclear '[[:space:]]', podríamos haber tecleado '[', después un espacio
469 literalmente, a continuación Control-V, después un TAB literal y un ']' --
470 Control-V indica a bash que queremos introducir un TAB "real" en lugar de una
471 expansión del comando. Es mucho más claro, especialmente en archivos de
472 comandos usar la clase de comandos '[[:space:]]'.
473 </p>
474
475 <p>
476 Bien, ahora la segunda expreg. '/^}/' apuntará a algún carácter '}' que
477 aparezca al comienzo de una nueva línea. Si nuestro código se ha formateado
478 correctamente, toparemos con ello con el final de nuestra función main(). Si no
479 lo está, no lo hará -- cuestión de trabajar con la coincidencia de patrones.
480 </p>
481
482 <p>
483 El comando <c>p</c> hace lo mismo que siempre, le dice a sed que imprima
484 explícitamente la línea, dado que estamos en el modo silencioso '-n'. Si se
485 intenta ejecutar el comando en una línea de código fuente en C, tratará de
486 mostrar el bloque completo main() { }, incluyendo el "main ()" inicial y el '}'
487 final.
488 </p>
489
490 </body>
491 </section>
492 <section>
493 <title>La próxima vez</title>
494 <body>
495
496 <p>
497 Ahora que hemos tratado los principios básicos, estamos listos para los
498 siguientes dos artículos. Si necesitamos más material acerca de sed, hay que
499 ser paciente -- se está elaborando. Mientras tanto, pueden consultarse los
500 siguientes recursos acerca de sed y de las expresiones regulares.
501 </p>
502
503 </body>
504 </section>
505 </chapter>
506
507 <chapter id="recursos">
508 <title>Recursos</title>
509 <section>
510 <title>Enlaces útiles</title>
511 <body>
512
513 <ul>
514 <li>
515 Leer los otros artículos acerca de sed de Daniel en developerWorks: "Sed
516 mediante ejemplos, <uri link="/doc/es/articles/l-sed2.xml">Parte 2</uri> y
517 <uri link="/doc/es/articles/l-sed3.xml">Parte 3</uri>.
518 </li>
519 <li>
520 Comprobar la excelente <uri
521 link="http://www.student.northpark.edu/pemente/sed/sedfaq.html">sed FAQ</uri>
522 de Eric Pement.
523 </li>
524 <li>
525 Se puede encontrar el código fuente de sed 3.02 en
526 <uri>ftp://ftp.gnu.org/pub/gnu/sed</uri>.
527 </li>
528 <li>
529 Se puede encontrar el nuevo sed 3.02.80 en <uri>ftp://alpha.gnu.org</uri>.
530 </li>
531 <li>
532 Eric Pement tiene también una lista muy práctica de <uri
533 link="http://www.student.northpark.edu/pemente/sed/sed1line.txt">sed one-liners</uri>
534 que cualquier aspirante a gurú sed debería consultar.
535 </li>
536 <li>
537 Si nos gustan los libros tradicionales, <uri
538 link="http://www.oreilly.com/catalog/sed2/">O'Reilly's sed &amp; awk, 2nd
539 Edition</uri> sería una gran elección.
540 </li>
541 <!-- FIXME BOTH DEAD and not possible to find other locations, sorry
542 <li>
543 Maybe you'd like to read <uri
544 link="http://www.softlab.ntua.gr/unix/docs/sed.txt">7th edition UNIX's sed
545 man page</uri> (circa 1978!).
546 </li>
547 <li>
548 Take Felix von Leitner's short <uri
549 link="http://www.math.fu-berlin.de/~leitner/sed/tutorial.html">sed
550 tutorial</uri>.
551 </li>
552 -->
553 <li>
554 Leer el artículo de David Mertz acerca del <uri
555 link="http://www-106.ibm.com/developerworks/linux/library/l-python5.html">
556 Procesamiento de texto bajo Python</uri> (en inglés) en developerWorks.
557 </li>
558 <!-- Dead link
559 <li>
560 Brush up on <uri link="http://vision.eng.shu.ac.uk/C++/misc/regexp/">using
561 regular expressions</uri> to find and modify patterns in text in this free,
562 dW-exclusive tutorial.
563 </li>
564 -->
565 <li>
566 Ver el <uri
567 link="http://www.python.org/doc/howto/regex/regex.html">Regular Expression
568 HOWTO</uri> (en inglés) de <uri link="http://python.org">Python.org</uri>.
569 </li>
570 <li>
571 Tener en cuenta el <uri
572 link="http://www.uky.edu/ArtsSciences/Classics/regex.html">Regular
573 Expression Overview</uri> (en inglés) de la Universidad de Kentucky.
574 </li>
575 </ul>
576
577 </body>
578 </section>
579 </chapter>
580
581 </guide>
582
583
584
585 1.1 xml/htdocs/doc/es/articles/l-sed2.xml
586
587 file : http://sources.gentoo.org/viewcvs.py/gentoo/xml/htdocs/doc/es/articles/l-sed2.xml?rev=1.1&view=markup
588 plain: http://sources.gentoo.org/viewcvs.py/gentoo/xml/htdocs/doc/es/articles/l-sed2.xml?rev=1.1&content-type=text/plain
589
590 Index: l-sed2.xml
591 ===================================================================
592 <?xml version='1.0' encoding="UTF-8"?>
593 <!-- $Header: /var/cvsroot/gentoo/xml/htdocs/doc/es/articles/l-sed2.xml,v 1.1 2007/11/02 14:41:56 yoswink Exp $ -->
594 <!DOCTYPE guide SYSTEM "/dtd/guide.dtd">
595
596 <guide link="/doc/es/articles/l-sed2.xml" disclaimer="articles" lang="es">
597 <title>Sed mediante ejemplos, Parte 2</title>
598
599 <author title="Autor">
600 <mail link="drobbins@g.o">Daniel Robbins</mail>
601 </author>
602 <author title="Traductor">
603 <mail link="LinuxBlues@×××××××××.org">LinuxBlues</mail>
604 </author>
605
606
607 <abstract>
608 Sed es un poderoso y compacto editor de flujos de texto. En este artículo, el
609 segundo de la serie, Daniel muestra cómo realizar sustituciones de cadenas;
610 crear archivos de comandos más amplios y usar los comandos de sed para añadir,
611 insertar y modificar una línea.
612 </abstract>
613
614 <!-- The original version of this article was published on IBM developerWorks,
615 and is property of Westtech Information Services. This document is an updated
616 version of the original article, and contains various improvements made by the
617 Gentoo Linux Documentation team -->
618
619 <version>1.2</version>
620 <date>2005-10-09</date>
621
622 <chapter>
623 <title>Cómo aprovechar más el editor UNIX</title>
624 <section>
625 <title>¡Sustitución!</title>
626 <body>
627
628 <p>
629 Veamos uno de los comandos más útiles de sed, el de sustitución. Usándolo,
630 podemos reemplazar una cadena en concreto o la expresión regular coincidente
631 con otra cadena. He aquí un ejemplo del uso más básico de este comando:
632 </p>
633
634 <pre caption="El uso más básico del comando de sustitución">
635 $ <i>sed -e 's/foo/bar/' miarchivo.txt</i>
636 </pre>
637
638 <p>
639 El comando anterior sacará los contenidos de miarchivo.txt a stdout, con la
640 primera aparición de 'foo' (si es que hay alguna) reemplazada en cada línea por
641 la cadena 'bar'. Por favor, hay que tener en cuenta que he dicho la primera
642 aparición en cada línea, a pesar de que esto no es lo que se desea normalmente.
643 Cuando quiero realizar la sustitución de una cadena, normalmente la quiero
644 realizar globalmente. Dicho con otras palabras, quiero reemplazar la expresión
645 todas las veces que se muestra, como sigue:
646 </p>
647
648 <pre caption="Reemplazar todas las coincidencias en cada línea">
649 $ <i>sed -e 's/foo/bar/g' miarchivo.txt</i>
650 </pre>
651
652 <p>
653 La opción adicional 'g' después de la última barra le indica a sed que debe
654 realizar el reemplazo de forma global.
655 </p>
656
657 <p>
658 He aquí algunas otras cosas que se deben saber acerca del comando de
659 sustitución <c>s///</c>. La primera es que se trata de un comando y de un
660 comando únicamente; no hay ninguna dirección mostrada en los ejemplos
661 anteriores. Lo cual significa que el comando <c>s///</c> puede usarse con
662 directivas acerca de las direcciones a las cuales se aplicará, como se muestra:
663 </p>
664
665 <pre caption="Especificar las líneas a las que se aplicará el comando">
666 $ <i>sed -e '1,10s/enchantment/entrapment/g' miarchivo2.txt</i>
667 </pre>
668
669 <p>
670 El ejemplo anterior causará que todas las veces que aparezca 'enchantment' se
671 reemplace por 'entrapment', pero sólo hasta la línea 10, inclusive.
672 </p>
673
674 <pre caption="Especificar más opciones">
675 $ <i>sed -e '/^$/,/^FIN/s/colinas/montañas/g' miarchivo3.txt</i>
676 </pre>
677
678 <p>
679 Este ejemplo cambiará 'colinas' por 'montañas', pero únicamente en los bloques
680 de texto que comiencen con una línea en blanco, y que terminen con una línea
681 que comience con los tres caracteres 'FIN', inclusive.
682 </p>
683
684 <p>
685 Otra de las buenas cosas acerca del comando <c>s///</c> es que tenemos muchas
686 opciones cuando usamos estos <c>/</c> separadores. Si estamos realizando la
687 sustitución de una cadena y la expresión regular o el reemplazo tiene muchas
688 barras, podemos cambiar el separador especificando un carácter distinto después
689 de la 's'. Por ejemplo, lo siguiente cambiará el contenido cambiando
690 <path>/usr/local</path> por <path>/usr</path>:
691 </p>
692
693 <pre caption="Reemplazar todas las apariciones de una cadena con otra">
694 $ <i>sed -e 's:/usr/local:/usr:g' milista.txt</i>
695 </pre>
696
697 <note>
698 En este ejemplo, estamos usando los dos puntos como separador. Si alguna vez
699 necesitamos especificar el carácter separador en nuestra expresión regular hay
700 que ponerle antes una barra invertida.
701 </note>
702
703 </body>
704 </section>
705 <section>
706 <title>La caótica confusión con las expreg</title>
707 <body>
708
709 <p>
710 Hasta ahora, únicamente hemos realizado una simple sustitución de cadenas.
711 Aunque esto puede ser muy útil, podemos también buscar expresiones regulares.
712 Por ejemplo, el siguiente comando sed encontrará una frase que comience con
713 '&lt;' y termine con '&gt;', y que contenga cualquier número de caracteres
714 entremedias. Esta frase se borrará (será reemplazada por una cadena sin
715 contenido):
716 </p>
717
718 <pre caption="Borrar la frase especificada">
719 $ <i>sed -e 's/&lt;.*&gt;//g' miarchivo.html</i>
720 </pre>
721
722 <p>
723 Un buen comienzo con un archivo de comandos sed sería eliminar todas las
724 etiquetas HTML de un archivo, pero no funcionará de forma correcta, debido a
725 algo que hace especiales a las expresiones regulares. ¿Cuál es la razón? Cuando
726 sed intenta encontrar la expresión regular en una línea, encuentra la
727 coincidencia más larga en la línea. Esto no era ningún problema en mi anterior
728 artículo acerca de sed, dado que estaba usando los comandos <c>d</c> y
729 <c>p</c>, que borrarían la línea completa de todas formas. Pero cuando usamos
730 el comando <c>s///</c>, es muy diferente, dado que todo aquello con lo que
731 coincida la expresión regular será reemplazado con la cadena de sustitución, o
732 en este caso, eliminado. Lo cual significa que, en el ejemplo anterior,
733 convertirá la siguiente línea:
734 </p>
735
736 <pre caption="ejemplo de código HTML">
737 &lt;b&gt;Esto&lt;/b&gt; es lo que &lt;b&gt;I&lt;/b&gt; quería decir.
738 </pre>
739
740 <p>
741 en esta otra:
742 </p>
743
744 <pre caption="Efecto indeseado">
745 quería decir.
746 </pre>
747
748 <p>
749 en lugar de hacer esto otro, que era lo que pretendíamos:
750 </p>
751
752 <pre caption="Efecto deseado">
753 Esto es lo que quería decir.
754 </pre>
755
756 <p>
757 Afortunadamente, hay una forma sencilla de resolverlo. En lugar de teclear una
758 expresión regular que indique "un carácter '&lt;' seguido de cualquier número
759 de caracteres y que termine con un carácter '&gt;'". Lo cual tendrá el efecto
760 de apuntar a la menor coincidencia posible, en lugar de a la mayor de ellas. El
761 nuevo comando sería similar a este:
762 </p>
763
764 <pre caption="">
765 $ <i>sed -e 's/&lt;[^&gt;]*&gt;//g' miarchivo.html</i>
766 </pre>
767
768 <p>
769 En el ejemplo anterior, el '[^&gt;]' especifica un "carácter que no sea '&gt;'"
770 y el '*' después del mismo completa la expresión para significar "cero o más
771 caracteres que no sean '&gt;'". Recomiendo probar este comando con algunos
772 archivos HTML de ejemplo, encauzarlos con more y comprobar los resultados.
773 </p>
774
775 </body>
776 </section>
777 <section>
778 <title>Coincidencia con más caracteres</title>
779 <body>
780
781 <p>
782 La sintaxis de expresiones regulares '[ ]' tiene más opciones adicionales. Para
783 especificar un rango de caracteres se puede usar '-', siempre y cuando no esté
784 ni en la primera ni en la última posición, como se muestra a continuación:
785 </p>
786
787 <pre caption="Especificar un rango de caracteres">
788 '[a-x]*'
789 </pre>
790
791 <p>
792 Apuntará a cero o más caracteres, siempre que cada uno de ellos sea una 'a',
793 'b','c'...'v','w','x'. Además, la clase de caracteres '[:space:]' está
794 disponible para coincidir con espacios en blanco. He aquí una lista bastante
795 completa de clases de caracteres:
796 </p>
797
798
799 <table>
800 <tr>
801 <th>Clase de carácter</th>
802 <th>Descripción</th>
803 </tr>
804 <tr>
805 <ti>[:alnum:]</ti>
806 <ti>Alfanumérico [a-z A-Z 0-9]</ti>
807 </tr>
808 <tr>
809 <ti>[:alpha:]</ti>
810 <ti>Alfabético [a-z A-Z]</ti>
811 </tr>
812 <tr>
813 <ti>[:blank:]</ti>
814 <ti>Espacios o tabuladores</ti>
815 </tr>
816 <tr>
817 <ti>[:cntrl:]</ti>
818 <ti>Cualquier carácter de control</ti>
819 </tr>
820 <tr>
821 <ti>[:digit:]</ti>
822 <ti>Dígitos numéricos [0-9]</ti>
823 </tr>
824 <tr>
825 <ti>[:graph:]</ti>
826 <ti>Cualquier carácter visible (no espacios en blanco)</ti>
827 </tr>
828 <tr>
829 <ti>[:lower:]</ti>
830 <ti>Minúsculas [a-z]</ti>
831 </tr>
832 <tr>
833 <ti>[:print:]</ti>
834 <ti>Caracteres que no sean de control</ti>
835 </tr>
836 <tr>
837 <ti>[:punct:]</ti>
838 <ti>Caracteres de puntuación</ti>
839 </tr>
840 <tr>
841 <ti>[:space:]</ti>
842 <ti>Espacio en blanco</ti>
843 </tr>
844 <tr>
845 <ti>[:upper:]</ti>
846 <ti>Mayúsculas [A-Z]</ti>
847 </tr>
848 <tr>
849 <ti>[:xdigit:]</ti>
850 <ti>Dígitos hexadecimales [0-9 a-f A-F]</ti>
851 </tr>
852 </table>
853
854 <p>
855 Es una gran ventaja usar clases de caracteres siempre que sea posible, dado que
856 se adaptan mejor a las locales no inglesas (incluyendo caracteres con acentos
857 siempre que sea necesario, etc.).
858 </p>
859
860 </body>
861 </section>
862 <section>
863 <title>Asuntos de sustitución avanzada</title>
864 <body>
865
866 <p>
867 Nos hemos detenido con la realización de simples e incluso complejas
868 sustituciones directas, pero sed puede hacer mucho más. Podemos referirnos a
869 partes o a cadenas enteras con las que coincida la expresión regular y usar
870 estas partes para construir la cadena de reemplazo. Como ejemplo, digamos que
871 estamos respondiendo a un mensaje. El siguiente ejemplo pondrá el prefijo "Rafa
872 dijo: " a cada frase:
873 </p>
874
875 <pre caption="Añadir un prefijo a cada frase con cierta cadena">
876 $ <i>sed -e 's/.*/Rafa dijo: &amp;/' msjorig.txt</i>
877 </pre>
878
879 <p>
880 La salida será similar a esta:
881 </p>
882
883 <pre caption="Salida del anterior comando">
884 Rafa dijo: Hola Jaime,
885 Rafa dijo:
886 Rafa dijo: ¡Seguro que me gusta este material acerca de sed!
887 Rafa dijo:
888 </pre>
889
890 <p>
891 En este ejemplo, usamos el carácter '&amp;' en la cadena de reemplazo, que le
892 indica a sed que inserte la expresión regular completa con la que coincida. Por
893 lo que todo lo que coincidió con '.*' (el mayor grupo de cero o más caracteres
894 en la línea, o la línea completa) puede ser introducido en la cadena de
895 reemplazo, incluso en múltiples ocasiones. Esto está muy bien, pero sed es
896 mucho más poderoso aún.
897 </p>
898
899 </body>
900 </section>
901 <section>
902 <title>Aquellos maravillosos paréntesis con barras invertidas</title>
903 <body>
904
905 <p>
906 Aún mejor que con '&amp;', el comando <c>s///</c> nos permite definir regiones
907 en nuestra expresión regular, y podemos referirnos a estas regiones específicas
908 en nuestra cadena de reemplazo. Como ejemplo, digamos que tenemos un archivo
909 que contiene el siguiente texto:
910 </p>
911
912 <pre caption="Cita del texto">
913 foo bar oni
914 eeny meeny miny
915 larry curly moe
916 jimmy the weasel
917 </pre>
918
919 <p>
920 Ahora, digamos que queremos escribir un archivo de comandos sed que reemplace
921 "eeny meeny miny" con "Victor eeny-meeny Von miny", etc. Para hacerlo, primero
922 deberíamos escribir una expresión regular con la que coincidan las tres
923 cadenas, separadas por espacios:
924 </p>
925
926 <pre caption="Coincidir con la expresión regular">
927 '.* .* .*'
928 </pre>
929
930 <p>
931 Aquí está. Ahora, definiremos regiones insertando paréntesis con barras
932 invertidas alrededor de cada región de nuestro interés:
933 </p>
934
935 <pre caption="Definición de regiones">
936 '\(.*\) \(.*\) \(.*\)'
937 </pre>
938
939 <p>
940 Esta expresión regular funcionará exactamente igual que la anterior, excepto
941 porque definirá tres regiones lógicas a las que podremos referirnos en nuestra
942 cadena de reemplazo. He aquí el archivo de comandos final:
943 </p>
944
945 <pre caption="Archivo de comandos final">
946 $ <i>sed -e 's/\(.*\) \(.*\) \(.*\)/Victor \1-\2 Von \3/' miarchivo.txt</i>
947 </pre>
948
949 <p>
950 Como puede verse, nos referimos a cada región delimitada por un paréntesis
951 tecleando '\x', donde x es el número de región, comenzando por uno. El
952 resultado será el siguiente:
953 </p>
954
955 <pre caption="Resultado del anterior comando">
956 Victor foo-bar Von oni
957 Victor eeny-meeny Von miny
958 Victor larry-curly Von moe
959 Victor jimmy-the Von weasel
960 </pre>
961
962 <p>
963 A medida que uno se familiariza con sed, puede realizarse un procesamiento de
964 textos realmente poderoso con un mínimo de esfuerzo. Pensemos ahora en cómo
965 habríamos afrontado este mismo problema con nuestro lenguaje para crear
966 archivos de comandos favorito -- ¿habríamos sido capaces de encontrar la
967 solución con una sola línea?
968 </p>
969
970 </body>
971 </section>
972 <section>
973 <title>Combinarlo todo</title>
974 <body>
975
976 <p>
977 A medida que creamos archivos de comandos con sed más complejos, necesitaremos
978 la capacidad para introducir más de un comando. Hay varias formas de lograrlo.
979 Primero podemos usar puntos y comas entre los comandos. Por ejemplo, en esta
980 serie de comandos se emplea el comando '=', que le indica a sed que muestre el
981 número de línea, así como el comando <c>p</c>, que le indica a sed que muestre
982 la línea (dado que estamos en el modo '-n'):
983 </p>
984
985 <pre caption="Primer método, puntos y comas">
986 $ <i>sed -n -e '=;p' myfile.txt</i>
987 </pre>
988
989 <p>
990 Cada vez que se indiquen dos o más comandos, se ejecutará cada comando (en
991 orden) para cada línea del archivo. En el ejemplo anterior, primero se aplica
992 el comando '=' a la línea 1, y después se le aplica el comando <c>p</c>.
993 Entonces sed procede con la línea 2 y repite el proceso. Mientras que los
994 puntos y comas son muy útiles, hay ciertas situaciones en las que no
995 funcionará. Otra alternativa sería usar dos opciones -e para especificar dos
996 comandos separados:
997 </p>
998
999 <pre caption="Segundo método, múltiples -e">
1000 $ <i>sed -n -e '=' -e 'p' miarchivo.txt</i>
1001 </pre>
1002
1003 <p>
1004 De todas formas, cuando nos adentremos en comandos más complejos para añadir e
1005 insertar texto, no será suficiente con múltiples opciones '-e'. Para archivos
1006 de comandos complejos con varias líneas, el método más adecuado es poner todos
1007 esos comandos en un archivo diferente. Después haremos referencia a este
1008 archivo de comandos con la opción -f:
1009 </p>
1010
1011 <pre caption="Tercer método, archivo externo con comandos">
1012 $ <i>sed -n -f miscomandos.sed miarchivo.txt</i>
1013 </pre>
1014
1015 <p>
1016 Este método, aunque parezca menos conveniente, siempre funcionará.
1017
1018 </p>
1019
1020 </body>
1021 </section>
1022 <section>
1023 <title>Múltiples comandos en una sola dirección</title>
1024 <body>
1025
1026 <p>
1027 A veces, podemos querer especificar múltiples comandos que se apliquen en una
1028 sola dirección. Lo cual es realmente útil cuando se realizan montones de
1029 <c>s///</c> para modificar palabras o la sintaxis de un archivo. Para realizar
1030 múltiples comandos en una sola dirección, introducimos nuestros comandos sed en
1031 un archivo y usamos los caracteres de llaves '{ }' para agruparlos, como sigue:
1032 </p>
1033
1034 <pre caption="Introducción de múltiples comandos por dirección">
1035 1,20{
1036 s/[Ll]inux/GNU\/Linux/g
1037 s/samba/Samba/g
1038 s/posix/POSIX/g
1039 }
1040 </pre>
1041
1042 <p>
1043 El ejemplo anterior aplicará tres comandos de sustitución desde la línea 1 a la
1044 20, inclusive. Se pueden expresar también direcciones con expresiones regulares
1045 o una combinación de ambas:
1046 </p>
1047
1048 <pre caption="Combinación de ambos métodos">
1049 1,/^END/{
1050 s/[Ll]inux/GNU\/Linux/g
1051 s/samba/Samba/g
1052 s/posix/POSIX/g
1053 p
1054 }
1055 </pre>
1056
1057 <p>
1058 Este ejemplo aplicará todos los comandos entre '{ }' a las líneas que se
1059 encuentren entre la primera y aquella que comience con las letras "END", o
1060 hasta el final del archivo, si no se encuentra "END" antes.
1061 </p>
1062
1063 </body>
1064 </section>
1065 <section>
1066 <title>Añadir, insertar y cambiar de línea</title>
1067 <body>
1068
1069 <p>
1070 Ahora que estamos escribiendo archivos de comandos sed en archivos separados,
1071 podemos aprovechar los comandos para añadir, insertar y cambiar de línea. Estos
1072 comandos insertarán una línea después de la línea actual, insertarán una línea
1073 antes de la línea actual o reemplazarán a la línea actual en el espacio de
1074 patrones. Pueden usarse para insertar múltiples líneas en su salida. El comando
1075 para insertar líneas se usa como sigue:
1076 </p>
1077
1078 <pre caption="Usar el comando para insertar líneas">
1079 i\
1080 Esta línea se insertará antes de cada línea
1081 </pre>
1082
1083 <p>
1084 Si no se especifica ninguna dirección en la que aplicar este comando, se
1085 aplicará a cada línea y producirá un resultado como el siguiente:
1086 </p>
1087
1088 <pre caption="Resultados del anterior comando">
1089 Esta línea se insertará antes de cada línea
1090 línea 1 aquí
1091 Esta línea se insertará antes de cada línea
1092 línea 2 aquí
1093 Esta línea se insertará antes de cada línea
1094 línea 3 aquí
1095 Esta línea se insertará antes de cada línea
1096 línea 4 aquí
1097 </pre>
1098
1099 <p>
1100 Si se quieren insertar varias líneas antes de la actual, se pueden añadir
1101 agregando una barra invertida a la línea anterior, como se muestra:
1102 </p>
1103
1104 <pre caption="Insertar varias líneas antes de la actual">
1105 i\
1106 inserta esta línea\
1107 y esta otra\
1108 y esta otra\
1109 y, ¡ah!, esta también.
1110 </pre>
1111
1112 <p>
1113 El comando para añadir funciona de forma similar, pero insertará una línea o
1114 líneas después de la actual en el espacio de patrones. Se usa como sigue:
1115 </p>
1116
1117 <pre caption="Añadir líneas después de la actual">
1118 a\
1119 Añade esta línea después de cada línea. ¡Gracias! :)
1120 </pre>
1121
1122 <p>
1123 Por otra parte, el comando para cambiar de línea reemplazará la línea actual
1124 en el espacio de patrones, y se usa como se indica:
1125 </p>
1126
1127 <p>
1128 Dado que el comando para añadir, insertar y cambiar de línea necesitan ser
1129 indicados en varias líneas, es necesario teclearlos en archivos de comandos de
1130 texto e indicar a sed que los ejecute con la opción '-f'. Usar los otros
1131 métodos de sed para introducir comandos resultará problemático.
1132 </p>
1133
1134 </body>
1135 </section>
1136 <section>
1137 <title>La próxima vez</title>
1138 <body>
1139
1140 <p>
1141 La próxima vez, en el último artículo acerca de sed en esta serie, mostraré
1142 muchos ejemplos excelentes de uso en el mundo real para muchos tipos diferentes
1143 de tareas. No solamente mostraré lo que los archivos de comandos hacen sino
1144 porqué lo hacen. Después de consultarlo, dispondremos de muchas ideas
1145 adicionales excelentes acerca de cómo usar sed en nuestros proyectos. ¡Nos
1146 vemos !
1147 </p>
1148
1149 </body>
1150 </section>
1151 </chapter>
1152
1153 <chapter>
1154 <title>Recursos</title>
1155 <section>
1156 <title>Enlaces útiles</title>
1157 <body>
1158
1159 <ul>
1160 <li>
1161 Leer los otros artículos acerca de sed de Daniel en developerWorks: "Sed
1162 mediante ejemplos, <uri link="/doc/es/articles/l-sed1.xml">Parte 1</uri> y
1163 <uri link="/doc/es/articles/l-sed3.xml">Parte 3</uri>.
1164 </li>
1165 <li>
1166 Comprobar la excelente <uri
1167 link="http://www.student.northpark.edu/pemente/sed/sedfaq.html">se FAQ</uri>
1168 de Eric Pement.
1169 </li>
1170 <li>
1171 Se puede encontrar el código fuente de sed 3.02 en
1172 <uri>ftp://ftp.gnu.org/pub/gnu/sed</uri>.
1173 </li>
1174 <li>
1175 Se puede encontrar el nuevo sed 3.02.80 en <uri>ftp://alpha.gnu.org</uri>.
1176 </li>
1177 <li>
1178 Eric Pement tiene también una lista muy práctica de <uri
1179 link="http://www.student.northpark.edu/pemente/sed/sed1line.txt">sed one-liners</uri>
1180 que cualquier aspirante a gurú sed debería consultar.
1181 </li>
1182 <li>
1183 Si nos gustan los libros tradicionales, <uri
1184 link="http://www.oreilly.com/catalog/sed2/">O'Reilly's sed &amp; awk, 2nd
1185 Edition</uri> sería una gran elección.
1186 </li>
1187 <!-- FIXME BOTH DEAD and no other locations, sorry
1188 <li>
1189 Maybe you'd like to read <uri
1190 link="http://www.softlab.ntua.gr/unix/docs/sed.txt">7th edition UNIX's sed
1191 man page</uri> (circa 1978!).
1192 </li>
1193 <li>
1194 Take Felix von Leitner's short <uri
1195 link="http://www.math.fu-berlin.de/~leitner/sed/tutorial.html">sed
1196 tutorial</uri>.
1197 </li>
1198 <li>
1199 Brush up on <uri link="http://vision.eng.shu.ac.uk/C++/misc/regexp/">using
1200 regular expressions</uri> to find and modify patterns in text in this free,
1201 dW-exclusive tutorial.
1202 </li>
1203 -->
1204 </ul>
1205
1206 </body>
1207 </section>
1208 </chapter>
1209
1210 </guide>
1211
1212
1213
1214 1.1 xml/htdocs/doc/es/articles/l-sed3.xml
1215
1216 file : http://sources.gentoo.org/viewcvs.py/gentoo/xml/htdocs/doc/es/articles/l-sed3.xml?rev=1.1&view=markup
1217 plain: http://sources.gentoo.org/viewcvs.py/gentoo/xml/htdocs/doc/es/articles/l-sed3.xml?rev=1.1&content-type=text/plain
1218
1219 Index: l-sed3.xml
1220 ===================================================================
1221 <?xml version='1.0' encoding="UTF-8"?>
1222 <!-- $Header: /var/cvsroot/gentoo/xml/htdocs/doc/es/articles/l-sed3.xml,v 1.1 2007/11/02 14:41:56 yoswink Exp $ -->
1223 <!DOCTYPE guide SYSTEM "/dtd/guide.dtd">
1224
1225 <guide link="/doc/es/articles/l-sed3.xml" disclaimer="articles" lang="es">
1226 <title>Sed mediante ejemplos, Parte 3</title>
1227
1228 <author title="Autor">
1229 <mail link="drobbins@g.o">Daniel Robbins</mail>
1230 </author>
1231 <author title="Traductor">
1232 <mail link="LinuxBlues@×××××××××.org">LinuxBlues</mail>
1233 </author>
1234
1235 <abstract>
1236 Sed es un poderoso y compacto editor de flujos de texto. En este artículo, el
1237 segundo de la serie, Daniel muestra cómo realizar sustituciones de cadenas;
1238 crear archivos de comandos más amplios y usar los comandos de sed para añadir,
1239 insertar y modificar una línea.
1240 </abstract>
1241
1242 <!-- The original version of this article was published on IBM developerWorks,
1243 and is property of Westtech Information Services. This document is an updated
1244 version of the original article, and contains various improvements made by the
1245 Gentoo Linux Documentation team -->
1246
1247 <version>1.2</version>
1248 <date>2005-10-09</date>
1249
1250 <chapter>
1251 <title>Subir de nivel: Manejo de datos, al estilo de sed</title>
1252 <section>
1253 <title>Muscular sed</title>
1254 <body>
1255
1256 <p>
1257 En <uri link="l-sed2.xml">mi segundo artículo acerca de sed</uri>, ofrecí
1258 ejemplos que mostraban el funcionamiento de sed, pero muy pocos de estos
1259 ejemplos realizaban algo realmente útil. En este artículo final acerca de sed
1260 es el momento de cambiar esto y poner a sed en buen uso. Mostraré algunos
1261 ejemplos excelentes que no sólo mostrarán el extraordinario poder de sed, sino
1262 que harán algunas cosas realmente elegantes y prácticas. Por ejemplo, en la
1263 segunda mitad del artículo, mostraré cómo he diseñado un archivo de comandos
1264 sed que convierte un archivo .QIF del programa de finanzas Quicken de Intuit en
1265 un archivo de texto con buen formato. Antes de llegar a eso, veamos algunos
1266 ejemplos menos complicados, aunque útiles, de archivos de comandos sed.
1267 </p>
1268
1269 </body>
1270 </section>
1271 <section>
1272 <title>Traducción de texto</title>
1273 <body>
1274
1275 <p>
1276 Nuestro primer ejemplo práctico, un archivo de comandos que convierte texto de
1277 tipo UNIX a texto en el formato DOS/Windows. Como muy probablemente sabemos, el
1278 texto de DOS/Windows contiene un CR (retorno de carro) y un LF (avance de
1279 línea) al final de cada línea, mientras que el texto UNIX solamente tiene un
1280 avance de línea. Pueden presentarse ocasiones en las que necesitemos mover
1281 algún texto UNIX a un sistema Windows, y este archivo de comandos realizará los
1282 pasos necesarios por nosotros.
1283 </p>
1284
1285 <pre caption="Conversión de formato entre UNIX y Windows">
1286 $ <i>sed -e 's/$/\r/' miunix.txt > midos.txt</i>
1287 </pre>
1288
1289 <p>
1290 Con este comando, la expresión regular '$' apuntará al final de la línea, y la
1291 '\r' le indica a sed que inserte un retorno de carro justo antes de llegar al
1292 mismo. Insertamos un retorno de carro antes de un avance de línea y conseguido,
1293 un CR/LF finaliza cada línea. Por favor, hay que considerar que '\r' únicamente
1294 será reemplazado por un CR si se usa GNU sed 3.02.80 o posterior. Si aún no se
1295 ha instalado GNU sed 3.02.80, ver <uri link="l-sed1.xml">mi primer artículo
1296 acerca de sed</uri> para obtener las instrucciones necesarias.
1297 </p>
1298
1299 <p>
1300 No sería capaz de enumerar todas las veces que he descargado algún archivo de
1301 comandos de ejemplo o de código en C, para toparme con que estaba en el formato
1302 DOS/Windows. Mientras que a algunos programas les trae sin cuidado manejar el
1303 formato DOS/Windows CR/LF en archivos de texto, a otros les importa y mucho --
1304 un ejemplo a destacar sería bash que lo inicia tan pronto como encuentra un
1305 retorno de carro. El siguiente comando sed convertirá texto con el formato
1306 DOS/Windows al formato de confianza UNIX:
1307 </p>
1308
1309 <pre caption="Convertir código en C desde Windows a UNIX">
1310 $ <i>sed -e 's/.$//' midos.txt > miunix.txt</i>
1311 </pre>
1312
1313 <p>
1314 El funcionamiento de este comando es muy simple: nuestra expresión regular a
1315 sustituir coincide con el último carácter de la línea, el cual será un retorno
1316 de carro. Lo reemplazamos con nada, dando lugar a que sea eliminado de la
1317 salida completamente. Si usamos este comando y notamos que el último carácter
1318 de cada línea ha sido eliminado, entonces habríamos especificado un archivo de
1319 texto que ya estaba en formato UNIX, ¡por lo que no sería necesario!
1320 </p>
1321
1322 </body>
1323 </section>
1324 <section>
1325 <title>Revertir de líneas</title>
1326 <body>
1327
1328 <p>
1329 He aquí otra pequeña macro muy práctica. Con ella revertiremos las líneas en un
1330 archivo, de forma muy similar a lo que realiza el comando "tac" que se incluye
1331 en casi todas las distribuciones Linux. El nombre "tac" puede resultar confuso,
1332 dado que "tac" no cambia el orden de los caracteres en una línea (de derecha a
1333 izquierda), sino que cambia la posición de las líneas en un archivo (de abajo a
1334 arriba). Hacerle un tac al siguiente archivo:
1335 </p>
1336
1337 <pre caption="Archivo de muestra">
1338 foo
1339 bar
1340 oni
1341 </pre>
1342
1343 <p>
1344 ....produce la siguiente salida:
1345 </p>
1346
1347 <pre caption="Archivo resultante">
1348 oni
1349 bar
1350 foo
1351 </pre>
1352
1353 <p>
1354 Podemos hacer exactamente lo mismo con la siguiente macro en sed:
1355 </p>
1356
1357 <pre caption="Hacer lo mismo con una macro">
1358 $ <i>sed -e '1!G;h;$!d' avance.txt > retroceso.txt</i>
1359 </pre>
1360
1361 <p>
1362 Encontraremos este comando especialmente útil si estamos en un sistema FreeBSD,
1363 que no dispone del comando "tac". Aunque es muy práctica, es una muy buena idea
1364 saber porqué hace lo que hace. Vamos a diseccionarlo.
1365 </p>
1366
1367 </body>
1368 </section>
1369 <section>
1370 <title>Explicación de la reversión</title>
1371 <body>
1372
1373 <p>
1374 En primer lugar, esta macro contiene tres comandos sed separados por puntos y
1375 comas: '1!G', 'h' y '$!d'. Ahora es un buen momento para entender las
1376 direcciones empleadas para el primer y el tercer comando. Si el primer comando
1377 fuera '1G', la 'G' se aplicaría únicamente a la primera línea. De todas formas,
1378 hay un carácter '!' adicional -- este carácter '!' niega el direccionamiento,
1379 con lo que el comando 'G' se aplicará a todas las líneas excepto a la primera.
1380 Con respecto a la '$!d' estamos en una situación muy similar. Si el comando
1381 fuera '$d', lo aplicaría únicamente a la última línea del archivo (la dirección
1382 '$' es una forma simple de designar a la última línea). De todas formas, con el
1383 '!', '$!d' aplicará el comando 'd' a todas las líneas excepto a la última.
1384 Ahora, lo único que necesitamos es entender qué es lo que hacen los comandos.
1385 </p>
1386
1387 <p>
1388 Cuando ejecutamos nuestra macro para revertir las líneas, el primer comando que
1389 se lleva a cabo es 'h'. Este comando le indica a sed que copie los contenidos
1390 del espacio de patrones (la memoria intermedia que contiene la línea en la que
1391 estamos trabajando) al espacio de mantenimiento (una memoria intermedia
1392 temporal). Entonces se ejecuta el comando 'd', que elimina "foo" del espacio de
1393 patrones, por lo que no se imprime después de que se ejecuten todos los
1394 comandos para esta línea.
1395 </p>
1396
1397 <p>
1398 Ahora, la segunda línea. Después de leer "bar" en el espacio de patrones, se
1399 lleva a cabo el comando 'G', que añade los contenidos del espacio de
1400 mantenimiento ("foo\n") al espacio de patrones ("bar\n"), dando como resultado
1401 "bar\n\foo\n" en nuestro espacio de patrones. El comando 'h' vuelve a ponerlo
1402 en el espacio de mantenimiento como medida de seguridad y 'd' borra la línea
1403 del espacio de patrones, por lo que no se imprimirá.
1404 </p>
1405
1406 <p>
1407 Para la última línea "oni", se repiten los mismos pasos, excepto que los
1408 contenidos del espacio de patrones no se eliminan (debido al '$!' anterior a
1409 'd') y los contenidos del espacio de patrones (tres líneas) se imprimen en
1410 stdout.
1411 </p>
1412
1413 <p>
1414 Ahora, es el momento de hacer una transformación de datos mucho más poderosa
1415 con sed.
1416 </p>
1417
1418 </body>
1419 </section>
1420 <section>
1421 <title>QIF mágico con sed</title>
1422 <body>
1423
1424 <p>
1425 Durante las últimas semanas, he estado considerando comprar Quicken para hacer
1426 balances en mis cuentas bancarias. Quicken es un buen programa de finanzas y
1427 realizaría el trabajo con resultados brillantes. Pero, después de pensar acerca
1428 de ello, decidí que podía escribir sin demasiados esfuerzos algún programa que
1429 hiciera un balance de mi talonario. Después de todo, pensé, ¡soy un
1430 desarrollador de software!
1431 </p>
1432
1433 <p>
1434 Desarrollé un pequeño programa de balance de mi talonario (usando awk) que
1435 calcula el balance manejando un archivo de texto que contenía todas mis
1436 transacciones. Después de trabajar con el mismo, lo mejoré de forma que podía
1437 tener en cuenta varias categorías de crédito y débito, tal y como Quicken podía
1438 hacer. Pero había una característica más que quería añadir. He cambiado mis
1439 cuentas recientemente a un banco que tiene una interfaz Web para manejar mis
1440 cuentas en línea. Un día me dí cuenta de que el sitio web de mi banco me
1441 permitía descargar la información de mi cuenta en formato .QIF; Acto seguido,
1442 decidí que sería muy interesante convertir esa información a formato texto.
1443 </p>
1444
1445 </body>
1446 </section>
1447 <section>
1448 <title>La historia de dos formatos</title>
1449 <body>
1450
1451 <p>
1452 Antes de que veamos el formato QIF, he aquí el formato de mi archivo
1453 talonario.txt:
1454 </p>
1455
1456 <pre caption="Mi talonario.txt">
1457 28 Aug 2000 food - - Y Supermarket 30.94
1458 25 Aug 2000 watr - 103 Y Check 103 52.86
1459 </pre>
1460
1461 <p>
1462 En mi archivo, todos los campos están separados por uno o más tabuladores, con
1463 una transacción por línea. Después de la fecha, el siguiente campo lista el
1464 tipo de gasto (o "-" si es un ingreso). El tercer campo lista el tipo de
1465 ingreso (o "-" si es un gasto). Después hay un campo para el número de cheque
1466 (de nuevo, con un "-" si no contiene nada), un campo de transacción realizada
1467 ("Y" o "N"), un comentario y el precio en dólares.
1468 Ahora, estamos listos para echar un vistazo al formato QIF. Cuando vi el
1469 archivo descargado con un visor de textos, esto es lo que pude observar:
1470 </p>
1471
1472 <pre caption="Ejemplo de formato QIF">
1473 !Type:Bank
1474 D08/28/2000
1475 T-8.15
1476 N
1477 PCHECKCARD SUPERMARKET
1478 ^
1479 D08/28/2000
1480 T-8.25
1481 N
1482 PCHECKCARD PUNJAB RESTAURANT
1483 ^
1484 D08/28/2000
1485 T-17.17
1486 N
1487 PCHECKCARD SUPERMARKET
1488 </pre>
1489
1490 <p>
1491 Después de revisar el archivo, no fue demasiado complicado figurarse el formato
1492 -- ignorando la primera línea, el formato es como sigue:
1493 </p>
1494
1495 <pre caption="Formato del archivo">
1496 D&lt;fecha&gt;
1497 T&lt;precio de la transacción&gt;
1498 N&lt;número de cheque&gt;
1499 P&lt;descripción&gt;
1500 ^
1501 <comment>(este es el separador de campos)</comment>
1502 </pre>
1503
1504 </body>
1505 </section>
1506 <section>
1507 <title>Comenzar el proceso</title>
1508 <body>
1509
1510 <p>
1511 Cuando nos ponemos manos a la obra con un proyecto de sed como este, no hay que
1512 desanimarse -- sed nos permite adecuar los datos gradualmente a su formato
1513 final. A medida que progresamos en el mismo, podemos ir depurando nuestra macro
1514 sed hasta que el resultado sea justo el que esperábamos. No es necesario
1515 obtenerlo en el primer intento.
1516 </p>
1517
1518 <p>
1519 Para comenzar, he creado un archivo denominado <path>qiftrans.sed</path> y he
1520 comenzado a manipular los datos:
1521 </p>
1522
1523 <pre caption="qiftrans.sed">
1524 1d
1525 /^^/d
1526 s/[[:cntrl:]]//g
1527 </pre>
1528
1529 <p>
1530 El primer comando '1d' elimina la primera línea, y el segundo elimina todos los
1531 malditos caracteres '^' de la salida. La última línea elimina todos los
1532 caracteres de control que puedan existir en el archivo. Dado que estoy
1533 trabajando con un formato de archivos extraño, quiero evitar el riesgo de
1534 encontrar cualquier carácter de control a lo largo del archivo. Ahora es el
1535 momento de añadir mayor poder de procesamiento a esta macro tan básica:
1536 </p>
1537
1538 <pre caption="Macro básica mejorada">
1539 1d
1540 /^^/d
1541 s/[[:cntrl:]]//g
1542 /^D/ {
1543 s/^D\(.*\)/\1\tOUTY\tINNY\t/
1544 s/^01/Jan/
1545 s/^02/Feb/
1546 s/^03/Mar/
1547 s/^04/Apr/
1548 s/^05/May/
1549 s/^06/Jun/
1550 s/^07/Jul/
1551 s/^08/Aug/
1552 s/^09/Sep/
1553 s/^10/Oct/
1554 s/^11/Nov/
1555 s/^12/Dec/
1556 s:^\(.*\)/\(.*\)/\(.*\):\2 \1 \3:
1557 }
1558 </pre>
1559
1560 <p>
1561 Primero añado una dirección '/^D/' para que sed únicamente comience a procesar
1562 cuando encuentra el primer carácter del campo de la fecha de un archivo QIF,
1563 'D'. Todos los comandos entre las llaves se ejecutarán en orden tan pronto como
1564 sed lea una de esas líneas en su espacio de patrones.
1565 </p>
1566
1567 <p>
1568 La primera línea entre llaves transformará una línea como esta:
1569 </p>
1570
1571 <pre caption="Primera línea antes del cambio">
1572 D08/28/2000
1573 </pre>
1574
1575 <p>
1576 en otra que será como esta:
1577 </p>
1578
1579 <pre caption="Primera línea después del cambio">
1580 08/28/2000 OUTY INNY
1581 </pre>
1582
1583 <p>
1584 Por supuesto, este formato no es perfecto por ahora, pero está bien.
1585 Depuraremos gradualmente los contenidos del espacio de patrones al seguir. Las
1586 siguientes 12 líneas realizan la labor de convertir la fecha en el formato con
1587 tres letras, además, la última línea elimina las tres barras de la fecha. Con
1588 lo cual obtenemos una línea como la siguiente:
1589 </p>
1590
1591 <pre caption="Aspecto final de la línea">
1592 Aug 28 2000 OUTY INNY
1593 </pre>
1594
1595 <p>
1596 Los campos OUTY e INNY nos sirven como ubicaciones que se reemplazarán más
1597 tarde. No puedo especificarlos ahora, porque si la cantidad de dólares es
1598 negativa, querré indicar OUTY e INNY como "misc" y "-", mientras que si la
1599 cantidad de dólares es positiva, querré indicarlos como "-" e "inco"
1600 respectivamente. Dado que no se ha tenido acceso a la cantidad de dólares
1601 todavía, prefiero usar ubicadores por ahora.
1602 </p>
1603
1604 </body>
1605 </section>
1606 <section>
1607 <title>Depuración</title>
1608 <body>
1609
1610 <p>
1611 Es el momento para depurarlo aún más:
1612 </p>
1613
1614 <pre caption="Mayor depuración">
1615 1d
1616 /^^/d
1617 s/[[:cntrl:]]//g
1618 /^D/ {
1619 s/^D\(.*\)/\1\tOUTY\tINNY\t/
1620 s/^01/Jan/
1621 s/^02/Feb/
1622 s/^03/Mar/
1623 s/^04/Apr/
1624 s/^05/May/
1625 s/^06/Jun/
1626 s/^07/Jul/
1627 s/^08/Aug/
1628 s/^09/Sep/
1629 s/^10/Oct/
1630 s/^11/Nov/
1631 s/^12/Dec/
1632 s:^\(.*\)/\(.*\)/\(.*\):\2 \1 \3:
1633 N
1634 N
1635 N
1636 s/\nT\(.*\)\nN\(.*\)\nP\(.*\)/NUM\2NUM\t\tY\t\t\3\tAMT\1AMT/
1637 s/NUMNUM/-/
1638 s/NUM\([0-9]*\)NUM/\1/
1639 s/\([0-9]\),/\1/
1640 }
1641 </pre>
1642
1643 <p>
1644 Las siguientes siete líneas son un poco complicadas, por lo que las cubriremos
1645 en detalle. Primero, encontramos tres comandos 'N' en una columna. El comando
1646 'N' le indica a sed que lea la siguiente línea de la entrada y que la añada al
1647 espacio de patrones actual. Los tres comandos 'N' dan lugar a que las tres
1648 siguientes líneas se añadan a la memoria intermedia de nuestro espacio de
1649 patrones actual, y ahora nuestra línea será como esta:
1650 </p>
1651
1652 <pre caption="Nuevo aspecto de nuestras líneas">
1653 28 Aug 2000 OUTY INNY \nT-8.15\nN\nPCHECKCARD SUPERMARKET
1654 </pre>
1655
1656 <p>
1657 El espacio de patrones de sed se ha deteriorado -- necesitamos eliminar las
1658 nuevas líneas adicionales y hacer cambios de formato adicionales. Para lograrlo
1659 usaremos el comando de sustitución. El patrón que deseamos encontrar es el
1660 siguiente:
1661 </p>
1662
1663 <pre caption="Eliminar líneas adicionales y aplicar un nuevo formato">
1664 '\nT.*\nN.*\nP.*'
1665 </pre>
1666
1667 <p>
1668 Con ello apuntaremos a una nueva línea, seguida por una 'T', seguida de cero o
1669 más caracteres, seguida por otra nueva línea, seguida por una 'N' con cualquier
1670 número de caracteres, seguida por una 'P', seguida de cualquier número de
1671 caracteres. Esta expresión regular coincidirá con las tres líneas que acabamos
1672 de añadir al espacio de patrones. Pero queremos darle otro formato a esta
1673 región, no reemplazarla por completo. La cifra en dólares, el número de cheque
1674 (en caso de haberlo) y la descripción deben reaparecer en nuestra cadena de
1675 reemplazo. Para hacerlo, subyugamos estas "partes interesantes" con paréntesis
1676 de barra invertida, por lo que podemos hacer alusión a los mismos en nuestra
1677 cadena de reemplazo (usando '\1', '\2\', y '\3' para indicar a sed dónde
1678 insertarlos). Este es el comando final:
1679 </p>
1680
1681 <pre caption="Comando final">
1682 s/\nT\(.*\)\nN\(.*\)\nP\(.*\)/NUM\2NUM\t\tY\t\t\3\tAMT\1AMT/
1683 </pre>
1684
1685 <p>
1686 Este comando transforma nuestra línea en:
1687 </p>
1688
1689 <pre caption="Resultado del comando anterior">
1690 28 Aug 2000 OUTY INNY NUMNUM Y CHECKCARD SUPERMARKET AMT-8.15AMT
1691 </pre>
1692
1693 <p>
1694 A pesar de que la línea está mejorando, hay algunas cosas que parecen a primera
1695 vista... interesantes. La primera es la estúpida cadena "NUMNUM" -- ¿para qué
1696 sirve? Lo veremos en las siguientes dos líneas de la macro sed, que
1697 reemplazarán "NUMNUM" con un "-", mientras que "NUM"&lt;number&gt;"NUM" será
1698 reemplazado con &lt;number&gt;. Como puede verse, subordinar el número de
1699 cheque con una estúpida etiqueta nos permite insertar un "-" si el campo está
1700 vacío.
1701 </p>
1702
1703 </body>
1704 </section>
1705 <section>
1706 <title>Retoques finales</title>
1707 <body>
1708
1709 <p>
1710 La última línea elimina un punto decimal a continuación de un número. Con lo
1711 cual convertimos cifras en dólares como "3,231.00" en "3231.00", que es el
1712 formato que empleo. Ha llegado el momento de echar un vistazo a la macro final:
1713 </p>
1714
1715 <pre caption="La macro final">
1716 1d
1717 /^^/d
1718 s/[[:cntrl:]]//g
1719 /^D/ {
1720 s/^D\(.*\)/\1\tOUTY\tINNY\t/
1721 s/^01/Jan/
1722 s/^02/Feb/
1723 s/^03/Mar/
1724 s/^04/Apr/
1725 s/^05/May/
1726 s/^06/Jun/
1727 s/^07/Jul/
1728 s/^08/Aug/
1729 s/^09/Sep/
1730 s/^10/Oct/
1731 s/^11/Nov/
1732 s/^12/Dec/
1733 s:^\(.*\)/\(.*\)/\(.*\):\2 \1 \3:
1734 N
1735 N
1736 N
1737 s/\nT\(.*\)\nN\(.*\)\nP\(.*\)/NUM\2NUM\t\tY\t\t\3\tAMT\1AMT/
1738 s/NUMNUM/-/
1739 s/NUM\([0-9]*\)NUM/\1/
1740 s/\([0-9]\),/\1/
1741 /AMT-[0-9]*.[0-9]*AMT/b fixnegs
1742 s/AMT\(.*\)AMT/\1/
1743 s/OUTY/-/
1744 s/INNY/inco/
1745 b done
1746 :fixnegs
1747 s/AMT-\(.*\)AMT/\1/
1748 s/OUTY/misc/
1749 s/INNY/-/
1750 :done
1751 }
1752 </pre>
1753
1754 <p>
1755 Las siguientes once líneas adicionales usan la sustitución y alguna
1756 funcionalidad de ramificación para perfeccionar la salida. Primero, deberíamos
1757 observar esta línea:
1758 </p>
1759
1760 <pre caption="Primera línea en la que merece la pena fijarse">
1761 /AMT-[0-9]*.[0-9]*AMT/b fixnegs
1762 </pre>
1763
1764 <p>
1765 Esta línea contiene un comando ramificado, que es de la forma "/expreg/b
1766 etiqueta". Si se encuentra en el espacio de patrones la expreg, sed ramificará
1767 la etiqueta fixnegs. Es muy sencillo encontrar esta etiqueta, que aparece en
1768 el código como ":fixnegs". Si la expreg no coincide, continúa con normalidad y
1769 sigue procesando el siguiente comando.
1770 </p>
1771
1772 <p>
1773 Ahora que entendemos cómo funciona el comando, vamos a ver las ramas. Si
1774 observamos la expresión regular ramificada, vemos que coincidirá con la cadena
1775 'AMT', seguida de un '-', seguida de cualquier número de dígitos y 'AMT'. Como
1776 es fácil figurarse, la expreg trata de forma especial las cantidades de dólares
1777 negativas. Anteriormente subordinamos las cantidades de dólares con cadenas
1778 'AMT' para que pudiésemos encontrarlas fácilmente después. Dado que la expreg
1779 sólo coincidirá con cifras de dólares que comiencen con un '-', nuestra rama
1780 sólo aparecerá cuando estemos manejando débitos. Si estamos manejando un débito
1781 OUTY debe quedar como 'misc', INNY debe quedar como '-' y debe quitar el signo
1782 negativo delante de la cantidad del débito. Si seguimos el código, veremos que
1783 eso es lo que hace exactamente. Si el ramal no se ejecuta, OUTY será
1784 reemplazado con un '-', e INNY se reemplazará por 'inco'. ¡Hemos terminado! La
1785 línea resultante es perfecta ahora:
1786 </p>
1787
1788 <pre caption="Línea resultante perfecta">
1789 28 Aug 2000 misc - - Y CHECKCARD SUPERMARKET -8.15
1790 </pre>
1791
1792 </body>
1793 </section>
1794 <section>
1795 <title>No hay que confundirse</title>
1796 <body>
1797
1798 <p>
1799 Como se ha visto, convertir datos usando sed no es tan complicado, siempre y
1800 cuando afrontemos el problema de forma incremental. No hay que tratar de hacer
1801 todo con un único comando sed, o todo a la primera. En lugar de esto, hay que
1802 trabajar gradualmente hasta que logremos nuestro objetivo, y continuaremos
1803 mejorando nuestra macro sed hasta que el resultado sea exactamente el que
1804 deseábamos. Sed contiene muchos recursos, espero que pronto nos familiaricemos
1805 con sed y con su funcionamiento interno y que continuemos creciendo en nuestro
1806 dominio de sed
1807 As you can see, converting data using sed isn't all that hard, as long as you
1808 approach the problem incrementally. Don't try to do everything with a single sed
1809 command, or all at once. Instead, gradually work your way toward the goal, and
1810 continue to enhance your sed script until your output looks just the way you
1811 want it to. Sed packs a lot of punch, and I hope that you've become very
1812 familiar with its inner workings and that you'll continue to grow in your sed
1813 mastery!
1814 </p>
1815
1816 <ul>
1817 <li>
1818 Leer los otros artículos acerca de sed de Daniel en developerWorks: "Sed
1819 mediante ejemplos, <uri link="/doc/es/articles/l-sed1.xml">Parte 1</uri> y
1820 <uri link="/doc/es/articles/l-sed2.xml">Parte 2</uri>.
1821 </li>
1822 <li>
1823 Comprobar la excelente <uri
1824 link="http://www.student.northpark.edu/pemente/sed/sedfaq.html">sed FAQ</uri>
1825 de Eric Pement.
1826 </li>
1827 <li>
1828 Se puede encontrar el código fuente de sed 3.02 en
1829 <uri>ftp://ftp.gnu.org/pub/gnu/sed</uri>.
1830 </li>
1831 <li>
1832 Se puede encontrar el nuevo sed 3.02.80 en <uri>ftp://alpha.gnu.org</uri>.
1833 </li>
1834 <li>
1835 Eric Pement tiene también una lista muy práctica de <uri
1836 link="http://www.student.northpark.edu/pemente/sed/sed1line.txt">sed one-liners</uri>
1837 que cualquier aspirante a gurú sed debería consultar.
1838 </li>
1839 <!-- FIXME BOTH DEAD and no other locations, sorry
1840 <li>
1841 Maybe you'd like to read <uri
1842 link="http://www.softlab.ntua.gr/unix/docs/sed.txt">7th edition UNIX's sed
1843 man page</uri> (circa 1978!).
1844 </li>
1845 <li>
1846 Take Felix von Leitner's short <uri
1847 link="http://www.math.fu-berlin.de/~leitner/sed/tutorial.html">sed
1848 tutorial</uri>.
1849 </li>
1850 <li>
1851 Brush up on <uri link="http://vision.eng.shu.ac.uk/C++/misc/regexp/">using
1852 regular expressions</uri> to find and modify patterns in text in this free,
1853 dW-exclusive tutorial.
1854 </li>
1855 -->
1856 </ul>
1857
1858 </body>
1859 </section>
1860 </chapter>
1861
1862 </guide>
1863
1864
1865
1866 --
1867 gentoo-commits@g.o mailing list