Sustituir contenido de un fichero desde la terminal

cambiar contenido fichero de texto desde la línea de comandos de LinuxSuele ser habitual encontrar en las explicaciones de Internet la necesidad de sustituir algún dato en un fichero de texto obligando para ello al usuario a localizar el archivo, hacer una búsqueda en su contenido y hacer el cambio pedido sin equivocarse en ninguno de los pasos.

No es una tarea excesivamente complicada pero si que puede resultar aburrida, innecesaria y propensa a errores.

Para uno de los artículos que voy a publicar próximamente se requiere hacer una operación de este tipo y, como imagino que no será la última vez que tengamos que hacer algo así he optado por publicar este artículo en el que explico cómo realizar, con una sola instrucción, algunas operaciones básicas sobre el contenido de un fichero de texto desde la línea de comandos.

Texto de ejemplo

Sea el contenido del fichero /tmp/frases.txt, que usaremos en nuestros ejemplos, el siguiente

Francisco compra el Pan
Odio que me despierte el panadero
Compra pan cuando estés acampando
Tengo congelado algo de pan de la semana pasada

Veamos qué podemos hacer con él

Buscar y reemplazar un texto

Sustituir texto

Si lanzamos desde la terminal un

sed 's/pan/XXXX/g' /tmp/frases.txt

obtendremos como resultado

Francisco compra el Pan
Odio que me despierte el XXXXadero
Compra XXXX cuando estés acamXXXXdo
Tengo congelado algo de XXXX de la semana pasada

Ignorar mayúsculas y minúsculas

En la primera frase se nos ha escapado Pan para evitarlo debemos lanzar el comando sed del siguiente modo

sed 's/pan/XXXX/gi' /tmp/frases.txt

NOTA: Observa el /gi al final del patrón

obtendremos como resultado

Francisco compra el XXXX
Odio que me despierte el XXXXadero
Compra XXXX cuando estés acamXXXXando
Tengo congelado algo de XXXX de la semana pasada

Sustituir palabras completas

En los ejemplos anteriores encontramos que se han producido sustituciones de texto en palabras como panadero y acampando. Para evitarlo utilizaremos /b del siguiente modo

sed 's/pan\b/XXXX/gi' /tmp/frases.txt

obteniendo como resultado

Francisco compra el XXXX
Odio que me despierte el panadero
Compra XXXX cuando estés acampando
Tengo congelado algo de XXXX de la semana pasada

Líneas de inicio y fin

Si queremos que sólo se cambie el texto comprendido entre dos líneas del fichero (ambas incluidas) deberemos recurrir al siguiente comando

sed '2,3s/pan/XXXX/gi' /tmp/frases.txt

NOTA: observa el 2,3 que indica que los cambios deben realizarse en las líneas 2 y 3 dejando inalteradas el resto.

NOTA: observa igualmente que he quitado el /b para que sustituya cualquier ocurrencia de pan sin tener en cuenta si es, o no, una palabra completa o está dentro de otra; de este modo conseguimos que se vean cambios en ambas líneas.

El resultado del comando anterior sería

Francisco compra el Pan
Odio que me despierte el XXXXadero
Compra XXXX cuando estés acamXXXXdo
Tengo congelado algo de pan de la semana pasada

De una línea hasta el final

Si queremos cambiar todas las ocurrencias desde una línea concreta hasta el final, lanzaremos el comando del siguiente modo

sed '2,$ s/pan/XXXX/gi' /tmp/frases.txt

observando que se ha utilizado $ en lugar del número de línea final para indicar que debe llegar hasta el final del fichero.

El resultado sería

Francisco compra el Pan
Odio que me despierte el XXXXadero
Compra XXXX cuando estés acamXXXXdo
Tengo congelado algo de XXXX de la semana pasada

Conclusión

Espero que el “tochaco” de comandos y ejemplos os sirva de referencia y os ayude a comprender cómo realizar sustituciones en el contenido de un fichero de texto plano utilizando la línea de comandos.

Como indico mi objetivos es poder utilizarlo como referencia en otros artículos (evitando de este modo a los lectores tener que realizar tareas propensas a error) pero nadie evita que este conocimiento pueda ser aplicado igualmente a scripts en bash que simplifiquen dichos procesos.


8 Respuestas a “Sustituir contenido de un fichero desde la terminal”


  1. 1 Lify Douglas Pain 30 enero 2011 a las 4:21 am

    Excelente!!! La verdad es que en este blog siempre encuentro tips muy utiles y detallados que ayudan mucho a comprender que estamos haciendo.
    Gracias

  2. 3 Markus 21 septiembre 2011 a las 12:05 am

    Perdone mi indiscrección, pero llevo rato buscando por todo google una forma de usar sed que haga… por ejemplo en su frase de ejemplo , borrar todo lo que haya entre la palabra ‘que’ y ‘algo’. Primero borrando ambas incluidas, y segundo sin borrarlas.

    ¿Esos dos ejemplos, como se hacen? Espero pueda ayudarme,Gracias.

  3. 5 Markus 21 septiembre 2011 a las 8:30 am

    Gracias por contextarme.
    La verdad que jugando jugando he llegado a una solución, pero tiene un pequeño fallo, le mostrare con un ejemplo:

    La mariposa era bonita, con un ala rosa y un ala azul.

    Si por ejemplo yo quisiera borrar(o sustituir) todo lo que hay entre ‘era’ y ‘ala’… tendría problemas con el segundo ‘ala’ si escribo:

    sed ‘s/era.*ala//g’

    por que efectivamente me borra todo desde ‘era’ hasta ‘ala’ pero no el primero, si no el segundo ‘ala’, por lo que pienso que debo expecificar que quiero que sea siempre hasta el ‘primer ala’ que encuentre.

    Si se pregunta ¿para que demonios necesito hacer esto? ¿Para que me voy a comer la cabeza por algo así?

    Aquí le explico mi meta:
    Muchas veces usando Kompiz para crear webs de manera sencilla observo que en el modo wysiwyg va dotando a todas las etiquetas html de estilos css…. de manera style=”lo que sea chim pum; lo que sea mas; etc…;” cosa que no me gusta por que yo prefiero usar una hoja css a mi manera, yo quería hacer un script en bash que cogiera el archivo html que acabo de crear, y le borre toooooooodas las sentencias de estilos, y con esta sentencia sed:

    sed ‘s/style\=\”.*\;\”//g’

    efectivamente encuentra muchísimos ;” finales y me borra casi todo lo que encuentra en cada linea… al igual que pasa con el problema de ‘ala’ de arriba, es muy fustrante, llevo tres días con esto… y son tantas html que quiero editar… que mejor hubiese empezado hace tres días a borrarlas una a una…

    Bueno, espero que le interese lo demasiado el asunto, como para que le pueda dedicar algún minutejo más próximamente.

    Gracias por todo.
    Markus

    Por cierto, le felicito por el blog. Me ha gustado mucho. Saludos

  4. 6 Markus 22 septiembre 2011 a las 12:16 pm

    Bueno, sólo comentarle que ya lo he solucionado
    Frase:

    La mariposa era bonita, con un ala rosa y un ala azul.

    Para borrar o sustituir lo que hay entre “era” y el primer “ala” sin borrar ambas palabras:

    s/(?<=str1)(?:[^])*?(?=str2)//g

    Y para borrar o sustituir lo que hay entre "era" y el primer "ala" borrando ambas palabras inclusive:

    s/ era="[^"]*ala//g

    Por lo tanto para borrar las lineas de estilo en las tags html sería

    s/( cellspacing| bordercolor| border| style)="[^"]*"//g

    Un saludo, y gracias por todo.
    Hasta pronto.

    • 7 Informático de Guardia 22 septiembre 2011 a las 12:22 pm

      Gracias a ti @Markus por tomarte la molestia de comentar la solución (tengo que probarla en cuanto encuentre un hueco).

      Estuve mirando varias soluciones pero el que sed sea “greedy” me estaba fastidiando el resultado :(

      Enhorabuena y perdona que no haya podido dedicarle tanto tiempo como me hubiese gustado


  1. 1 BlogESfera.com Trackback en 31 enero 2011 a las 11:10 am

Deja un comentario

Fill in your details below or click an icon to log in:

Logo de WordPress.com

You are commenting using your WordPress.com account. Log Out / Cambiar )

Twitter picture

You are commenting using your Twitter account. Log Out / Cambiar )

Facebook photo

You are commenting using your Facebook account. Log Out / Cambiar )

Connecting to %s




Patrocinadores

informática y electrónica megastore online de electrónica y accesorios turismo en cuenca blog de coches y motor Anunciate aquí gana dinero con encuestas Alojamiento web de confianza Las últimas noticias de ciencia, tecnología, espacio y la actualidad internacional

¿Hablamos?

Escribe tu dirección de correo electrónico para suscribirte a este blog, y recibir notificaciones de nuevos mensajes por correo.

Únete a otros 1.280 seguidores

Participa

Histórico


Twitter

  • RT @malcer_quaid: "Nunca he conocido a nadie tan ignorante del que no pudiera aprender algo." - Buda 10 hours ago
  • RT @ildecortes: Eh! Han tirado 2 bengalas! 90 mil euros y 15 días, no? 1 day ago
  • @migmae Pues me voy a tener que buscar uno... gracias por avisar de su existencia :) 1 day ago
  • RT @Desalentado1: Cómo puede ser que para mantener la sanidad y educación,todo sean problemas y para Bankia habrá todo el capital necesa ... 1 day ago
  • RT @vcuevas: Rescatar Bankia, 19000 millones de €; mantener la sanidad y Educación, 10.000 m de €; que el Gobierno nos llame idiotas, n ... 2 days ago

Seguir

Get every new post delivered to your Inbox.

Únete a otros 1.280 seguidores