Archivo

Entradas Etiquetadas ‘class’

Sed… de venganza (1): Sustituyendo cadenas en múltiples archivos

Lunes, 28 de Junio de 2010 admin Sin comentarios

3846929292_60721fb24e

Es uno de los grandes desconocidos y tan temidos comandos de que disponemos. Y es cierto que a veces da pereza mirarse el manual cuando queremos hacer algo que sed podría hacer rápidamente.

Lo que cuento hoy es su uso más popular (porque sed se puede usar para muuuuuchas cosas) y es muy simple, sustituir en un stream un texto por otro (Donde dije digo, digo Diego).

Imaginemos un fichero de texto, para ser originales llamémosle README, y en el texto queremos cambiar la palabra “Ireland” por “Spain”. Podemos hacer lo siguiente:

$ sed ’s/Ireland/Spain/g’ README

y veremos en pantalla el texto. Para guardarlo en el mismo archivo, si buscamos por Internet, veremos cómo la gente se complica la vida (que no digo que sea malo, yo también me la complico un poco más abajo), pero podemos usar el modificador -i (que tiene algunas funciones curiosas).

Si ahora hacemos:

$ sed -i ’s/Ireland/Spain/g’ README

Los cambios se guardarán automáticamente en el fichero README. Pero si investigamos un poco más, y queremos rematar la faena podemos hacer:

$ sed -i~ ’s/Ireland/Spain/g’ README

En este caso, guardaremos el cambio en el fichero README y grabaremos en README~ una copia de seguridad del fichero antiguo. La extensión de la copia de seguridad podemos cambiarla haciendo por ejemplo:

$ sed -i.bak ’s/Ireland/Spain/g’ README

Para que la copia sea README.bak

Pero ahora viene algo interesante, con el parámetro -i podemos modificar todos los archivos que queramos, sed acepta en la entrada múltiples archivos, por lo que si en un directorio con muchos archivos queremos cambiar un texto (imaginad que habéis hecho un proyecto relativamente grande, y hay una función con un nombre un poco ridículo, curiosamente es la que más veces llamáis, y como vamos a enseñar el código fuente, no queremos que nadie lea eso), podremos hacer:

$ sed -i ’s/nombre_ridiculo/nombre_elegante/g’ *

Ahora bien, si el proyecto está en múltiples directorios, siempre podemos usar find para localizar los archivos de la siguiente forma:

find -name ‘*.c’ -exec sed -i ’s/nombre_ridiculo/nombre_elegante/g’ {} \;

Con toda esta línea, buscaremos todos los archivos con extensión .c dentro del directorio actual y subdirectorios y se los pasaremos a sed, con el modificador -exec de find, ejecutaremos el comando que especificamos, donde {} indica el nombre de archivo (que nos lo da find) y con \; indicamos el fin del comando y sus parametros.

Pero esto no termina aquí, sed soporta expresiones regulares, y si por ejemplo queremos coger todas las imágenes de un fichero html, cambiarlas de directorio y añadirles un class (inicialmente encontramos <img src=”foto.jpg” alt=”" /> , y queremos que salga <img class=”imagen” src=”/static/foto.jpg” alt=”" />) podemos hacer lo siguiente:

sed ’s/src=”\(.[a-zA-Z\.\_\/]*\)”/src=”\/static\/\1” class=”imagen”/g’ fichero.html

Lo que hay en negrita, corresponde a la expresión regular que determina el nombre del archivo (caracteres de la a a la z, de la A a la Z, puntos, guiones bajos, y barras (en la cadena de origen), en la cadena de destino escribimos \1 donde queremos que coloque el texto correspondiente a la expresión anterior, es decir donde queremos que coloque el nombre del archivo.

Ni que decir tiene que podemos hacer una mezcla de todo lo dicho en este post ( expresiones regulares, y sustitución en múltiples archivos dentro de múltiples subdirectorios y guardando backups ), y estaremos delante de una potente herramienta.

Lo malo de ejecutar sed, es que tenemos que escapar muchos caracteres,por lo menos ), (, ., \, / y seguro que encontramos alguno más; para ello, siempre que queramos introducir un carácter de esos, debemos poner una contra barra (\) delante.

Foto: albertopveiga (Flickr)

¡La web a mi gusto!

Viernes, 21 de Agosto de 2009 blakeyed Sin comentarios

A menudo, encontramos páginas web que pueden no ser compatibles con el navegador que estamos utilizando, o el sistema operativo en el que nos encontramos. Por ejemplo, últimamente, estoy usando Firefox 3.5 sobre Gentoo GNU/Linux. Es normal encontrarse webs diseñadas para Internet Explorer, o incluso puede que por las tipografías utilizadas no encajen bien en nuestro sistema.

En mi caso, hay una web que visito muy a menudo, y es la de mi proveedor de hosting en la que a veces, por ejemplo cuando quiero mandar un ticket; me veo obligado a utilizar el scroll horizontal, ya que al no especificar el ancho del textarea como propiedad en el CSS, lo han hecho en caracteres (con la propiedad COLS); veo un textarea mucho más grande que mi pantalla y cuando quiero revisar el mensaje que estoy mandando tengo que desplazarme constantemente de derecha a izquierda.

La solución fácil, sería que ellos cambiaran la forma en la que dimensionan el textarea, pero hay multitud de ocasiones en las que eso no se puede pedir. Tenemos el ejemplo del Manifiesto de Apoyo al autónomo de Punto Radio; la página, internamente está muy mal diseñada, y tras varios emails con el webmaster y éste decirme que la página no fallaba (la solución sería añadir un estilo a los input text del nombre y los apellidos, y ahí especificar el tamaño en pixels, se seguiría viendo igual en todas partes).
Punto Radio
Pero para nosotros y para andar por casa, vamos a utilizar el DOM Inspector (en el menú Herramientas), desde el que, como vemos más abajo hemos podido modificar la propiedad size de los input text en cuestión. (Para seleccionar el textbox pulsamos en el botón de arriba a la izquierda de la nueva ventana y luego pinchamos sobre el elemento dentro de la página; tras ello nos dejará seleccionar y modificar las propiedades con el botón derecho).
Punto Radio - Ahora se ve bien

Esto está bien para una web que vas a visitar una vez nada más. Pero hay veces que tienes que visitar una web de este tipo muchas veces, y es en este punto cuando tenemos que recurrir a extensiones como Chickenfoot o GreaseMonkey; estos dos, nos permiten ejecutar código javascript y dispararlo en un momento determinado, por ejemplo, al entrar en una web.

Para eso hice este script, que voy a utilizar para cuando tenga que enviar un ticket a mi proveedor de hosting:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
var alltags = new Array();

function redimensionalo(que)
{
    que.style.width='600px';
}

function CogeElementoPorClase(tipo, clase, quehacer)
{
  var alltags=document.getElementsByTagName(tipo);

  for (i=0; i<alltags.length; i++)
  {
    if (alltags[i].className==clase)
    {
    quehacer(alltags[i]);
    }
  }
}

CogeElementoPorClase('textarea', 'ClaseTextarea', redimensionalo);

El script, cogerá el textarea que tenga la clase ‘ClaseTextarea’ y llamará a la función redimensionalo que modificará su ancho y le establecerá 600px (como el elemento no tiene id no podemos utilizar getElementById). Gracias a una de las dos extensiones que mencioné antes, podremos hacer que ese script se ejecute nada más entrar en la sección de tickets de mi proveedor.

Aunque no termina todo ahí, podemos automatizar muchas acciones con estos dos programas, extraer información, hacer clicks en ciertas zonas de las páginas, etc; muchas veces necesitamos hacer tareas repetidas veces y estas extensiones pueden solucionarnos el día.

Visita otras webs de la red

Easy AdSense by Unreal