martes, 30 de agosto de 2016
lunes, 29 de agosto de 2016
-
nl - Numera
líneas
-
fold - Limita
cada línea a una longitud especificada
-
fmt - Un
formateador de texto simple
-
pr - Prepara
texto para imprimir
-
printf -
Formatea e imprime datos
-
groff - Un
sistema de formateo de documentos
viernes, 26 de agosto de 2016
miércoles, 24 de agosto de 2016
-
Del paquete Coreutils:
http://www.gnu.org/software/coreutils/manual/coreutils.html#Output-of-entire-files
http://www.gnu.org/software/coreutils/manual/coreutils.html#Operating-on-sorted-files
http://www.gnu.org/software/coreutils/manual/coreutils.html#Operating-on-fields
http://www.gnu.org/software/coreutils/manual/coreutils.html#Operating-on-characters
-
Del paquete Diffutils:
http://www.gnu.org/software/diffutils/manual/html_mono/diff.html
-
Hay otros muchos recursos online para sed,
en particular:
http://www.grymoire.com/Unix/Sed.html
http://sed.sourceforge.net/sed1line.txt
-
Prueba también a googlear “sed one liners”, “sed
cheat sheets”
lunes, 22 de agosto de 2016
jueves, 18 de agosto de 2016
Para comprobar ortográficamente un archivo de texto que contenga una prosa simple, puede usarse así:
aspell check textfile
donde textfile es el nombre del archivo a comprobar. Como ejemplo práctico, crearemos un archivo de texto simple llamado foo.txt que contengan algunos errores ortográficos intencionados:
[me@linuxbox ~]$ cat > foo.txt
The quick brown fox jimped over the laxy dog.
A continuación, comprobamos el archivo usando aspell:
[me@linuxbox ~]$ aspell check foo.txt
Como aspell es interactivo en el modo de comprobación, veremos una pantalla como esta:
The quick brown fox jimped over the laxy dog.
1) jumped 6) wimped
2) gimped 7) camped
3) comped 8) humped
4) limped 9) impede
5) pimped 0) umped
i) Ignore I) Ignore all
r) Replace R) Replace all
a) Add l) Add Lower
b) Abort x) Exit
?
En la parte de arriba de la pantalla, vemos nuestro texto con una palabra sospechosa señalada. En el centro, vemos diez sugerencias ortográficas numeradas del cero al nueve, seguida de una lista de otras opciones posibles. Finalmente, en la parte inferior, vemos un prompt preparado para aceptar nuestra elección.
Si pulsamos la tecla 1, aspell reemplaza la palabra incorrecta por la palabra "jumped" y se mueve a la siguiente palabra mal escrita, que es "laxy". Si seleccionamos el reemplazo "lazy", aspell la cambia y termina. Una vez que aspell ha terminado, podemos examinar nuestro archivo y ver que los errores han sido corregidos:
[me@linuxbox ~]$ cat foo.txt
The quick brown fox jumped over the lazy dog.
A menos que se le indique en la línea de comandos la opción --dont-backup, aspell crea una copia de seguridad del archivo con el texto original añadiéndole la extensión .bak al nombre del archivo.
Presumiendo de nuestra habilidad editando con sed, pondremos nuestros errores ortográficos de nuevo para que podamos reutilizar nuestro archivo.
[me@linuxbox ~]$ sed -i 's/lazy/laxy/; s/jumped/jimped/' foo.txt
La opción -i de sed para editar el archivo "in-situ", significa que en lugar de enviar la salida editada a la salida estándar, reescribirá el archivo con los cambios aplicados. También vemos la capacidad de colocar más de un comando de edición en la línea separándolos con un punto y coma.
A continuación, veremos como aspell puede manejar diferentes tipos de archivos de texto. Usando un editor de texto como vim (los aventureros pueden probar sed), añadiremos algunas etiquetas HTML a nuestro archivo:
<html>
<head>
<title>Mispelled HTML file</title>
</head>
<body>
<p>The quick brown fox jimped over the laxy dog.</p>
</body>
</html>
Ahora, si tratamos de comprobar la ortografía de nuestro archivo modificado, encontramos un problema. Si lo hacemos así:
[me@linuxbox ~]$ aspell check foo.txt
tendremos esto:
<html>
<head>
<title>Mispelled HTML file</title>
</head>
<body>
<p>The quick brown fox jimped over the laxy dog.</p>
</body>
</html>
1) HTML 4) Hamel
2) ht ml 5) Hamil
3) ht-ml 6) hotel
i) Ignore I) Ignore all
r) Replace R) Replace all
a) Add l) Add Lower
b) Abort x) Exit
?
aspell verá el contenido de las etiquetas HTML como errores ortográficos. El problema puede solucionarse incluyendo la opción de modo de comprobación -H (HTML), como esta:
[me@linuxbox ~]$ aspell -H check foo.txt
que tendrá como resultado esto:
<html>
<head>
<title>Mispelled HTML file</title>
</head>
<body>
<p>The quick brown fox jimped over the laxy dog.</p>
</body>
</html>
1) Mi spelled 6) Misapplied
2) Mi-spelled 7) Miscalled
3) Misspelled 8) Respelled
4) Dispelled 9) Misspell
5) Spelled 0) Misled
i) Ignore I) Ignore all
r) Replace R) Replace all
a) Add l) Add Lower
b) Abort x) Exit
?
El HTML se ignora y sólo las porciones no-HTML del archivo se comprueban. En este modo, el contenido de las etiquetas HTML son ignoradas y no se les comprueba la ortografía. Sin embargo, el contenido de las etiquetas ALT, que es bueno que se comprueben, sí se chequean en este modo.
Nota: Por defecto, aspell ignorará URLs y direcciones de correo electrónico en el texto. Este comportamiento puede ser modificado con opciones de la línea de comandos. También es posible especificar qué etiquetas son comprobadas y cuales son obviadas. Mira la man page de aspell para más detalles.
miércoles, 17 de agosto de 2016
lunes, 15 de agosto de 2016
En general, la forma en que funciona sed es que se le da un comando simple de edición (en la línea de comandos) o el nombre de un archivo de script que contenga múltiples comandos, y ejecuta estos comandos sobre cada línea de la secuencia de texto. Aquí tenemos un ejemplo muy simple de sed en acción:
[me@linuxbox ~]$ echo "front" | sed 's/front/back/'
back
En este ejemplo, producimos una secuencia de texto de una palabra usando echo y lo canalizamos a sed. sed, a su vez, ejecuta la instrucción s/front/back/ en el texto de la secuencia y produce la salida "back" como resultado. También podemos considerar este comando de forma parecida al comando "sustitución" (buscar y reemplazar) de vi.
Los comandos en sed comienzan con una sola letra. En el ejemplo anterior, el comando sustitución se representa con la letra s y es seguido por las cadenas de búsqueda y reemplazo, separadas por el carácter de la barra inclinada como separador. La elección del carácter separador es arbitraria. Por consenso, el carácter de la barra inclinada se usa a menudo, pero sed aceptará cualquier carácter que siga inmediatamente al comando como separador. Podríamos realizar el mismo comando de la siguiente forma:
[me@linuxbox ~]$ echo "front" | sed 's_front_back_'
back
Usar el carácter guion bajo inmediatamente tras el comando, lo convierte en el separador. La capacidad de establecer el separador puede usarse para realizar los comandos más legibles, como veremos.
La mayoría de los comandos en sed irán precedidos por una dirección , que especifica qué línea(s) de la secuencia de entrada será editada. Si se omite la dirección, el comando editor se ejecutará en cada línea de la secuencia de entrada. La forma más simple de dirección es un número de línea. Podemos añadir uno a nuestro ejemplo:
[me@linuxbox ~]$ echo "front" | sed '1s/front/back/'
back
Añadiendo la dirección 1 a nuestro comando hacemos que nuestra sustitución se realice en la primera línea de nuestra entrada de una línea. Si especificamos otro número:
[me@linuxbox ~]$ echo "front" | sed '2s/front/back/'
front
vemos que la edición no se ha realizado, ya que nuestra secuencia de entrada no tiene línea 2.
Las direcciones pueden ser expresadas de muchas formas. Aquí tenemos las más comunes:
Tabla 20-7: Notación de direcciones en sed
Dirección | Descripción |
n | Un número de línea donde n es un entero positivo. |
$ | La última línea |
/regexp/ | Lineas que coinciden con una expresión regular básica POSIX. Fíjate que la expresión regular se delimita por barras inclinadas. Opcionalmente, la expresión regular puede delimitarse por un carácter alternativo, especificando la expresión con \cregexpc, donde c es el carácter alternativo. |
addr1, addr2 | Un rango de líneas desde addr1 a addr2, ambos incluidos. Las direcciones pueden estar en cualquiera de las formas que vimos antes. |
first~step | Encuentra la línea representada por el número first, y luego cada línea siguiente con el intervalo step. Por ejemplo 1~2 se refiere a cada línea impar, 5~5 se refiere a la quinta línea y cada quinta línea después de ella. |
addr1, +n | Encuentra addr1 y las siguientes n líneas. |
addr! | Encuentra todas las líneas excepto addr, que puede estar en cualquiera de las formas anteriores. |
Probaremos diferentes tipos de direcciones usando el archivo distros.txt que usamos antes en este capítulo. Primero, una rango de números de línea:
[me@linuxbox ~]$ sed -n '1,5p' distros.txt
SUSE 10.2 12/07/2006
Fedora 10 11/25/2008
SUSE 11.0 06/19/2008
Ubuntu 8.04 04/24/2008
Fedora 8 11/08/2007
En este ejemplo, obtenemos un rango de líneas, comenzando con la línea 1 y continuando hasta la línea 5. Para hacerlo, usamos el comando p, que simplemente hace que una línea encontrada se muestre. Sin embargo, para que esto sea efectivo, tenemos que incluir la opción -n (la opción sin autoimpresión) para hacer que sed no muestre cada línea por defecto.
A continuación, probemos algunas expresiones regulares:
[me@linuxbox ~]$ sed -n '/SUSE/p' distros.txt
SUSE 10.2 12/07/2006
SUSE 11.0 06/19/2008
SUSE 10.3 10/04/2007
SUSE 10.1 05/11/2006
Incluyendo la expresión regular delimitada por barras inclinadas /SUSE/, podemos aislar las líneas que la contengan casi de la misma forma que con grep.
Finalmente, probaremos la negación añadiendo un signo de exclamación (!) a la dirección:
[me@linuxbox ~]$ sed -n '/SUSE/!p' distros.txt
Fedora 10 11/25/2008
Ubuntu 8.04 04/24/2008
Fedora 8 11/08/2007
Ubuntu 6.10 10/26/2006
Fedora 7 05/31/2007
Ubuntu 7.10 10/18/2007
Ubuntu 7.04 04/19/2007
Fedora 6 10/24/2006
Fedora 9 05/13/2008
Ubuntu 6.06 06/01/2006
Ubuntu 8.10 10/30/2008
Fedora 5 03/20/2006
Aquí vemos el resultado esperado: todas las líneas en el archivo excepto las que coinciden con la expresión regular.
Hasta ahora, hemos visto dos de los comandos de edición de sed, s y p. Aquí tenemos una lista completa de los comandos de edición básicos:
Tabla 20-8: comandos de edición básicos de sed
Comando | Descripción |
= | Muestra el número de línea actual. |
a | Añade texto tras la línea actual. |
d | Borra la línea actual. |
i | Inserta texto antes de la línea actual. |
p | Muestra la línea actual. Por defecto, sed imprime cada línea y sólo edita líneas que coinciden con una dirección especificada dentro del archivo. El comportamiento por defecto puede sobrescribirse especificando la opción -n. |
q | Sale de sed sin procesar más líneas. Si la opción -n no se especifica, muestra la línea actual. |
Q | Sale de sed sin procesar más líneas. |
s/regexp/replacement/ | Sustituye el contenido de replacement donde se encuentre regexp, replacement puede incluir el carácter &, que es equivalente al texto correspondiente a regexp. Además, replacement puede incluir las secuencias \1 a \9, que son el contenido de las correspondientes subexpresiones de regexp. Para saber más sobre ésto, mira el tema de retroreferencias que está más adelante. Tras la barra invertida posterior a replacement, puede especificarse una marca para modificar el comportamiento del comando s. |
y/set1/set2 | Realiza transliteración convirtiendo caracteres de set1 a los correspondientes caracteres en set2. Fíjate que al contrario que tr, sed requiere que ambas series tengan la misma longitud. |
El comando s es de lejos el comando de edición más comúnmente usado. Probaremos sólo algunas de sus capacidades realizando edición en nuestro archivo distros.txt. Vimos antes cómo el campo fecha en distros.txt no estaba en formato "compatible con ordenadores". Ya que la fecha está formateada MM/DD/YYY, y sería mejor (para ordenarla más fácilmente) si el formato fuera YYYY-MM-DD. Realizar este cambio en el archivo a mano llevaría mucho tiempo y sería propenso a errores, pero con sed, este cambio puede realizarse en un paso:
[me@linuxbox ~]$ sed 's/\([0-9]\{2\}\)\/\([0-9]\{2\}\)\/\([0-9]\{4\}\)$/\3-\1-\2/' distros.txt
SUSE 10.2 2006-12-07
Fedora 10 2008-11-25
SUSE 11.0 2008-06-19
Ubuntu 8.04 2008-04-24
Fedora 8 2007-11-08
SUSE 10.3 2007-10-04
Ubuntu 6.10 2006-10-26
Fedora 7 2007-05-31
Ubuntu 7.10 2007-10-18
Ubuntu 7.04 2007-04-19
SUSE 10.1 2006-05-11
Fedora 6 2006-10-24
Fedora 9 2008-05-13
Ubuntu 6.06 2006-06-01
Ubuntu 8.10 2008-10-30
Fedora 5 2006-03-20
¡Guau! Es un comando muy feo. Pero funciona. En sólo un paso, hemos cambiado el formato de fecha de nuestro archivo. También es un ejemplo perfecto de por qué las expresiones regulares son llamadas, a veces en broma, un medio de "sólo-escritura". Podemos escribirlas, pero a menudo no podemos leerlas. Antes de que estemos tentados a huir aterrorizados de este comando, veamos como ha sido construido. Primero, sabemos que el comando tendrá esta estructura básica:
sed 's/regexp/replacement/' distros.txt
Nuestro próximo paso es encontrar una expresión regular que aisle la fecha. Como está en formato MM/DD/YYYY y aparece al final de la línea, podemos usar una expresión como esta:
[0-9]{2}/[0-9]{2}/[0-9]{4}$
que encuentra dos dígitos, una barra, dos dígitos, una barra, cuatro dígitos y el final de la línea. Así que esto se ocupa de regexp, pero ¿qué pasa con replacement? Para manejar esto, tenemos que introducir una nueva capacidad de las expresiones regulares que aparecen en algunas aplicaciones que usan BRE. Esta capacidad se llama retroreferencias y funcionan así: Si aparece la secuencia \n en replacement donde n es un número del 1 al 9, la secuencia se referirá a la subexpresión correspondiente en la expresión regular precedente. Para crear las subexpresiones, simplemente la metemos entre paréntesis así:
([0-9]{2})/([0-9]{2})/([0-9]{4})$
Ahora tenemos tres subexpresiones. La primera contiene el mes, la segunda contiene el día del mes y la tercera contiene el año. Ahora podemos construir replacement como sigue:
\3-\1-\2
que nos da el año, un guión, el mes, un guión y el día.
Ahora nuestro comando tiene esta pinta:
sed 's/([0-9]{2})/([0-9]{2})/([0-9]{4})$/\3-\1-\2/' distros.txt
Tenemos dos problemas todavía. El primero es que las barras extra en nuestra expresión confundirán a sed cuando trate de interpretar el comando s. El segundo es que como sed, por defecto, acepta sólo expresiones regulares básicas, varios caracteres en nuestra expresión regular serán tratados como literales, en lugar de como metacaracteres. Podemos resolver ambos problemas con una generosa utilización de barras invertidas para escapar los caracteres ofensivos:
sed 's/\([0-9]\{2\}\)\/\([0-9]\{2\}\)\/\([0-9]\{4\}\)$/\3-\1-\2/' distros.txt
¡Y aquí lo tenemos!
Otra característica del comando s es el uso de marcas opcionales que pueden seguir a la cadena de reemplazo. La más importante es la marca g, que ordena a sed que aplique una búsqueda y reemplazo global a una línea, no sólo a la primera instancia, que es la opción por defecto. Aquí tenemos un ejemplo:
[me@linuxbox ~]$ echo "aaabbbccc" | sed 's/b/B/'
aaaBbbccc
Vemos que se ha realizado el reemplazo, pero sólo en la primera instancia de la letra "b", mientras que las siguientes instancias se han dejado sin cambios. Añadiendo la marca g, podemos cambiar todas las instancias:
[me@linuxbox ~]$ echo "aaabbbccc" | sed 's/b/B/g'
aaaBBBccc
Hasta ahora, sólo le hemos dado a sed comandos individuales a través de la línea de comandos. También es posible construir comandos más complejos en un archivo de script usando la opción -f. Para hacer una demostración, usaremos sed con nuestro archivo distros.txt para crear un informe. Nuestro informe mostrará un título arriba, nuestras fechas modificadas y todos los nombres de las distribuciones convertidos a mayúsculas. Para hacerlo, necesitaremos escribir un script, así que arrancaremos nuestro editor de texto y escribiremos los siguiente:
# sed script to produce Linux distributions report
1 i\
\
Linux Distributions Report\
s/\([0-9]\{2\}\)\/\([0-9]\{2\}\)\/\([0-9]\{4\}\)$/\3-\1-\2/
y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/
Guardaremos nuestro script de sed como distros.sed y lo ejecutaremos así:
[me@linuxbox ~]$ sed -f distros.sed distros.txt
Linux Distributions Report
SUSE 10.2 2006-12-07
FEDORA 10 2008-11-25
SUSE 11.0 2008-06-19
UBUNTU 8.04 2008-04-24
FEDORA 8 2007-11-08
SUSE 10.3 2007-10-04
UBUNTU 6.10 2006-10-26
FEDORA 7 2007-05-31
UBUNTU 7.10 2007-10-18
UBUNTU 7.04 2007-04-19
SUSE 10.1 2006-05-11
FEDORA 6 2006-10-24
FEDORA 9 2008-05-13
UBUNTU 6.06 2006-06-01
UBUNTU 8.10 2008-10-30
FEDORA 5 2006-03-20
Como podemos ver, nuestro script produce el resultado esperado, pero ¿cómo lo ha hecho? Echemos otro vistazo a nuestro script. Usaremos cat para numerar las líneas:
[me@linuxbox ~]$ cat -n distros.sed
1 # sed script to produce Linux distributions report
2
3 1 i\
4 \
5 Linux Distributions Report\
6
7 s/\([0-9]\{2\}\)\/\([0-9]\{2\}\)\/\([0-9]\{4\}\)
$/\3-\1-\2/
8 y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/
La línea uno de nuestro script es un comentario. Como muchos archivos de configuración y lenguajes de programación en sistemas Linux, los comentarios comienzan con el caracter # y siguen con texto legible por humanos. Los comentarios pueden colocarse en cualquier parte del script (aunque no dentro de los propios comandos) y son útiles para las personas que necesiten identificar y/o mantener el script.
La línea 2 es una línea en blanco. Como los comentarios, las líneas en blanco deben añadirse para mejorar la legibilidad.
Muchos comandos sed soportan direcciones de línea. Se usan para especificar en qué líneas de entrada hay que actuar. Las direcciones de línea pueden expresarse como números de línea individuales, rangos de números de líneas y el número especial de línea "$" que indica la última línea de la entrada.
Las líneas 3 a 6 contienen texto a insertar en la dirección 1, la primera línea de la entrada. Al comando i le sigue la secuencia barra invertida-retorno de carro para producir un retorno de carro escapado, o lo que se llama un carácter de continuación de línea. Esta secuencia, que puede usarse en muchas circunstancias incluyendo scripts de shell, permite insertar un retorno de carro en una secuencia de texto sin indicar al intérprete (en este caso sed) que se ha alcanzado el final de la línea. Los comandos i, y de igual forma, a (que añade texto, en lugar de insertarlo) y c (que reemplaza texto), permiten múltiples líneas de texto siempre que cada línea, excepto la última, termine con el carácter continuación de línea. La sexta línea de nuestro script es realmente el final de nuestro texto insertado y termina con un simple retorno de carro, en lugar de con un carácter de continuación de línea, señalándole el final al comando i.
Nota: Un carácter de continuación de línea lo forman una barra invertida seguida inmediatamente por un retorno de carro. No se permiten espacios intermedios.
La línea 7 es nuestro comando de búsqueda y reemplazo. Como no está precedido por una dirección, cada línea de la secuencia de entrada está sometida a su acción.
La línea 8 realiza transliteración de las letras minúsculas a letras mayúsculas. Fíjate que al contrario que tr, el comando y de sed no soporta rangos de caracteres (por ejemplo, [a-z]), ni soporta clases de caracteres POSIX. De nuevo, como el comando y no está precedido por una dirección, se aplica a cada línea de la secuencia de entrada.
sábado, 13 de agosto de 2016
echo "secret text" | tr a-zA-Z n-za-mN-ZA-M
frperg grkg
Realizando el mismo procedimiento una segunda vez obtenemos la traducción:
echo "frperg grkg" | tr a-zA-Z n-za-mN-ZA-M
secret text
Numerosos programas de correo electrónico y lectores de noticias de Usenet soportan cifrado ROT13. Wikipedia tiene un buen artículo sobre el asunto:
http://en.wikipedia.org/wiki/ROT13
viernes, 12 de agosto de 2016
[me@linuxbox ~]$ echo "lowercase letters" | tr a-z A-Z
LOWERCASE LETTERS
Como podemos ver, tr funciona con la entrada estándar, y muestra sus resultados en la salida estándar. tr acepta dos argumentos: una serie de caracteres de donde convertir y una serie correspondiente de caracteres hacia donde convertir. Las series de caracteres pueden expresarse de tres formas diferentes:
-
Una lista enumerada. Por ejemplo,
ABCDEFGHIJKLMNOPQRSTUVWXYZ
-
Un rango de caracteres. Por ejemplo, A-Z.
Fíjate que este método está sujeto a menudo a los mismos
problemas que otros comandos, debido a la secuencia de ordenado de la configuración regional, y por
lo tanto hay que usarlo con precaución.
-
Clases de caracteres POSIX. Por ejemplo, [:upper:].
[me@linuxbox ~]$ echo "lowercase letters" | tr [:lower:] A
AAAAAAAAA AAAAAAA
Además de la transliteración, tr permite que los caracteres sean simplemente eliminados de la cadena de entrada. Antes, en este capítulo, vimos el problema de convertir archivos de texto MS-DOS a texto estilo-Unix. Para realizar esta conversión, los caracteres de retorno de carro necesitan ser eliminados del final de cada línea. Esto puede realizarse con tr de la forma siguiente:
tr -d '\r' < dos_file > unix_file
donde dos_file es el archivo a convertir y unix_file es el resultado. Esta forma del comando utiliza la secuencia de escape \r para representar el carácter retorno de carro. Para ver una lista completa de las secuencias y clases de caracteres que soporta tr, prueba:
[me@linuxbox ~]$ tr --help
tr también puede realizar otro truco. Usando la opción -s, tr puede "estrujar" (borrar) las instancias repetidas de un caracter:
[me@linuxbox ~]$ echo "aaabbbccc" | tr -s ab
abccc
Aquí tenemos un cadena que contiene caracteres repetidos. Especificando la lista "ab" a tr, eliminamos las instancias repetidas de las letras de la lista, mientras que deja los caracteres que no aparecen en la lista ("c") sin cambios. Fíjate que los caracteres repetidos debe estar contiguos. Si no lo están:
[me@linuxbox ~]$ echo "abcabcabc" | tr -s ab
abcabcabc
la eliminación no tendrá efecto.
jueves, 11 de agosto de 2016
miércoles, 10 de agosto de 2016
-
El archivo diff es muy pequeño, comparado con el tamaño del código fuente completo.
-
El archivo diff muestra de forma concisa el cambio a
realizar, permitiendo a los revisores del parche evaluarlo
rápidamente.
Para preparar un archivo diff para usarlo con patch, la documentación GNU (consulta la sección Para Saber Más al final del capítulo) sugiere usar diff de la siguiente manera:
diff -Naur old_file new_file > diff_file
Donde old_file y new_file son archivos individuales o directorios que contengan archivos. La opción r soporta recursividad en el árbol de directorios.
Una vez que el archivo diff ha sido creado, podemos aplicarlo para parchear el archivo antiguo y convertirlo en el nuevo archivo:
patch < diff_file
Lo demostraremos con nuestro archivo de pruebas:
[me@linuxbox ~]$ diff -Naur file1.txt file2.txt > patchfile.txt
[me@linuxbox ~]$ patch < patchfile.txt
patching file file1.txt
[me@linuxbox ~]$ cat file1.txt
b
c
d
e
En este ejemplo, hemos creado un archivo diff llamado patchfile.txt y luego hemos usado el programa patch para aplicar el parche. Fíjate que no hemos tenido que especificar un archivo de destino para patch, ya que el archivo diff (en formato unificado) ya contiene los nombres de archivo en la cabecera. Una vez que se aplica el parche, podemos ver que file1.txt ahora coincide con file2.txt.
patch tiene una gran número de opciones, y hay programas adicionales que pueden usarse para analizar y editar parches.
martes, 9 de agosto de 2016
Si usamos diff para ver nuestros archivos de ejemplo previos:
[me@linuxbox ~]$ diff file1.txt file2.txt
1d0
< a
4a4
> e
vemos su estilo de salida por defecto: una breve descripción de las diferencias entre los dos archivos. En el formato por defecto, cada grupo de cambios va precedido por un comando de cambio en la forma de un rango operación rango para describir las posiciones y tipos de cambios requeridos para convertir el primer archivo en el segundo:
Tabla 20-4: Comandos de cambio de diff
Cambio | Descripción |
r1ar2 | Añade las líneas en la posición r2 del segundo archivo a la posición r1 del primer archivo. |
r1cr2 | Cambia (reemplaza) las lineas en la posición r1 con las líneas en la posición r2 en el segundo archivo. |
r1dr2 | Borra las líneas en el primer archivo en la posición r1, que habrían aparecido en el rango r2 del segundo archivo. |
Cuando lo vemos usando el formato contextual (la opción -c), veremos ésto:
[me@linuxbox ~]$ diff -c file1.txt file2.txt
*** file1.txt 2008-12-23 06:40:13.000000000 -0500
--- file2.txt 2008-12-23 06:40:34.000000000 -0500
***************
*** 1,4 ****
- a
b
c
d
--- 1,4 ----
b
c
d
+ e
La salida comienza con los nombres de los dos archivos y sus fechas de modificación. El primer archivo está marcado con asteriscos y el segundo archivo está marcado con guiones. En el resto de la lista, estos marcadores simbolizarán sus respectivos archivos. A continuación, vemos grupos de cambios, incluyendo el número predeterminado de líneas de contexto existentes. En el primer grupo, vemos:
*** 1,4 ***
que indica líneas de la 1 a la 4 en el primer archivo. A continuación vemos:
--- 1,4 ---
que indica líneas de la 1 a la 4 en el segundo archivo. Dentro de un grupo de cambios, las líneas comienzan con uno de estos cuatro indicadores:
Tabla 20-5: Indicadores de cambios de diff en formato contextual
Indicador | Significado |
blank | Una línea de contexto mostrada. Indica que no hay ninguna diferencia entre los dos archivos. |
- | Una línea borrada. Esta línea aparecerá en el primer archivo pero no en el segundo. |
+ | Una línea añadida. Esta línea aparecerá en el segundo archivo pero no en el primero. |
! | Una línea modificada. Las dos versiones de la línea se mostrarán, cada una en su respectiva sección del grupo de cambio. |
[me@linuxbox ~]$ diff -u file1.txt file2.txt
--- file1.txt 2008-12-23 06:40:13.000000000 -0500
+++ file2.txt 2008-12-23 06:40:34.000000000 -0500
@@ -1,4 +1,4 @@
-a
b
c
d
+e
La diferencia más destacable entre los formatos contextual y unificado es la eliminación de las líneas duplicadas de contexto, haciendo que los resultados del formato unificado sean más cortos que los del formato contextual. En nuestro ejemplo anterior, vemos las marcas de tiempo de los archivos como los del formato contextual, seguidas de la cadena @@ -1,4 +1,4 @@. Esto indica las líneas del primer archivo y las líneas del segundo archivo descritas en el grupo de cambio. Tras ésto están las líneas en sí, con las tres líneas de contexto por defecto. Cada línea comienza con uno de tres posibles caracteres:
Tabla 20-6: Indicadores de cambios de diff en formato unificado
Carácter | Significado |
blank | Esta línea la comparten ambos archivos. |
- | Esta línea se eliminó del primer archivo. |
+ | Esta línea se añadió al primer archivo |
lunes, 8 de agosto de 2016
[me@linuxbox ~]$ cat > file1.txt
a
b
c
d
[me@linuxbox ~]$ cat > file2.txt
b
c
d
e
A continuación, compararemos los dos archivos usando comm:
[me@linuxbox ~]$ comm file1.txt file2.txt
a
b
c
d
e
Como podemos ver, comm produce tres columnas de salida. La primera columna contiene líneas exclusivas del primer archivo; la segunda columna, las líneas exclusivas del segundo archivo; la tercera columna contiene las líneas compartidas por ambos archivos. comm soporta opciones en la forma -n donde n es 1, 2 o 3. Cuando se usan, estas opciones especifican qué columna(s) suprimir. Por ejemplo, si sólo queremos obtener las líneas compartidas por ambos archivos, suprimiremos la salida de las columnas uno y dos:
[me@linuxbox ~]$ comm -12 file1.txt file2.txt
b
c
d
viernes, 5 de agosto de 2016
jueves, 4 de agosto de 2016
Para ver cómo se usa una operación join en una base de datos relacional, imaginemos una base de datos muy pequeña consistente en dos tablas, cada una con un único registro. La primera tabla, llamada CUSTOMERS, tiene tres campos: un número de cliente (CUSTNUM), el nombre del cliente (FNAME) y el apellido del cliente (LNAME):
CUSTNUM FNAME LNAME
======== ===== ======
4681934 John Smith
La segunda tabla se llama ORDERS y contiene cuatro campos: un número de pedido (ORDER-NUM), el número de cliente (CUSTNUM), la cantidad (QUAN) y el producto pedido (ITEM).
ORDERNUM CUSTNUM QUAN ITEM
======== ======= ==== ====
3014953305 4681934 1 Blue Widget
Fíjate que ambas tablas comparten el campo CUSTNUM. Esto es importante, ya que permite la relación entre las tablas.
Realizar una operación join nos permitiría combinar los campos en las dos tablas para conseguir un resultado útil, como preparar una factura. Usando los valores coincidentes en los campos CUSTNUM de ambas tablas, una operación join podría producir lo siguiente:
FNAME LNAME QUAN ITEM
===== ===== ==== ====
John Smith 1 Blue Widget
Para probar el programa join, necesitaremos crear un par de archivos con una clave compartida. Para hacerlo, usaremos nuestro archivo distros-by-date.txt. Desde este archivo, construiremos dos archivos adicionales, uno conteniendo las fechas de lanzamiento (que será nuestra clave compartida para esta demostración) y los nombres de la versión:
[me@linuxbox ~]$ cut -f 1,1 distros-by-date.txt > distros-names.txt
[me@linuxbox ~]$ paste distros-dates.txt distros-names.txt > distros-key-names.txt
[me@linuxbox ~]$ head distros-key-names.txt
11/25/2008 Fedora
10/30/2008 Ubuntu
06/19/2008 SUSE
05/13/2008 Fedora
04/24/2008 Ubuntu
11/08/2007 Fedora
10/18/2007 Ubuntu
10/04/2007 SUSE
05/31/2007 Fedora
04/19/2007 Ubuntu
y el segundo archivo, que contiene las fechas de lanzamiento y los números de versión:
[me@linuxbox ~]$ cut -f 2,2 distros-by-date.txt > distros-vernums.txt
[me@linuxbox ~]$ paste distros-dates.txt distros-vernums.txt > distros-key-vernums.txt
[me@linuxbox ~]$ head distros-key-vernums.txt
11/25/2008 10
10/30/2008 8.10
06/19/2008 11.0
05/13/2008 9
04/24/2008 8.04
11/08/2007 8
10/18/2007 7.10
10/04/2007 10.3
05/31/2007 7
04/19/2007 7.04
Ahora tenemos dos archivos con una clave compartida (el campo "fecha de lanzamiento"). Es importante señalar que los archivos deben estar ordenados por el campo clave para que join funcione apropiadamente.
[me@linuxbox ~]$ join distros-key-names.txt distros-key-vernums.txt | head
11/25/2008 Fedora 10
10/30/2008 Ubuntu 8.10
06/19/2008 SUSE 11.0
05/13/2008 Fedora 9
04/24/2008 Ubuntu 8.04
11/08/2007 Fedora 8
10/18/2007 Ubuntu 7.10
10/04/2007 SUSE 10.3
05/31/2007 Fedora 7
04/19/2007 Ubuntu 7.04
Fíjate también que, por defecto, join usa el espacio en blanco como el delimitador de campos de entrada y un espacio individual como el delimitador de campos de salida. Este comportamiento puede modificarse especificando opciones. Mira la man page de join para más detalles.