sábado, 20 de febrero de 2010

Reemplazar texto de varios archivos en Linux

bash.png


Voy a explicar cómo reemplazar un texto o cadena de caracteres en varios archivos. Por ejemplo, si tenemos diez archivos .txt en un directorio y queremos que donde aparece la palabra "Pepe", ahora ponga "Jose".






El comando


Se puede hacer fácilmente desde la consola de Linux, con un sólo comando. Sería algo así:




sed -i 's/palabra-vieja/palabra-nueva/g' *.txt


En nuestro caso sería:




sed -i 's/Pepe/Jose/g' *.txt


Este último comando sustituirá la palabra "Pepe" por "Jose" en todos los archivos txt del directorio actual.




¿Pero y si queremos hacer varias sustituciones ejecutando sólo un comando?






El script


Pues lo más sencillo es hacernos un script, en el que se hagan varias llamadas al comando sed, visto anteriormente. Podemos crearnos un archivo que se llame script.sh y que contendrá lo siguiente:




sed -i 's/Pepe/Jose/g' *.txt


sed -i 's/Manolo/Manuel/g' *.txt


sed -i 's/Nacho/Ignacio/g' *.txt


sed -i 's/Inma/Inmaculada/g' *.txt




Ahora ejecutando ese script, estaremos haciendo esas cuatro sustituciones en todos los archivos txt del directorio actual. Para ejecutar ese script, solo tendremos que teclear lo siguiente en la consola:




sh script.sh




39 Comentarios:

Anónimo dijo...

hola no se si me podria ayudar, soy nueva en linux y necesito insertar una línea de texto al inicio de un archivo.txt pero en muchos archivos .txt, prove con el comando cat (guardando la línea en un nuevo .txt) pero me une todos los archivos .txt en uno solo, y yo quiero la línea en cada archivo independiente. por favor si me pudieras ayudar te estaria muy agradecida

Felipe Martínez D. dijo...

Hola.

Puedes hacerlo así:

echo "Hola que tal?" > archivo1.txt
echo "Hola que tal?" > archivo2.txt
echo "Hola que tal?" > archivo3.txt
echo "Hola que tal?" > archivo4.txt


O crearte un script y escribir el mismo mensaje en todos los archivos .txt de un directorio:



#!/bin/bash

for FILE in *.txt
do
echo "Hola que tal?" >"${FILE}"
done



Saludos.

Andrés dijo...

Hola Felipe:
Quiero usar tu comando, pero el texto a cambiar y a sustituir es del tipo:
http://www.campsa.co.za/sites/campsa/campsa.nsf/
¿Como debo hacerlo?
Muchas gracias y un saludo
Andrés

Felipe Martínez D. dijo...

Hola Andrés.

En este caso, al estar utilizando URLs habría que utilizar otro carácter separador, que sería %. Ejemplo:

sed -i 's%http://www.campsa.co.za/sites/campsa/campsa.nsf/%http://www.google.es%g' *.txt

Fuente:
http://blog.networkpresence.co/?p=245

Saludos.

Anónimo dijo...

Hola,

¿Alguien sabe cómo se podría hacer para que sea extensible a toda una rama de un árbol de directorios?

Muchas gracias

Felipe Martínez D. dijo...

Hola.

Prueba con ésto:

find ./ -type f -exec sed -i "s/Pepe/Jose/g" '{}' \;                

Espero que te sirva.

Saludos.

Anónimo dijo...

Buenas Felipe

Muy buen post ;)

A ver si me puedes ayudar con una duda que tengo
A mi me gustaría que el valor a sustituir fuera una variable, algo como:

export Variable=/ruta/del/fichero/fichero.txt

sed -i 's/Nacho/$Variable/g' *.txt

No consigo ver como hacerlo...
Muchas gracias

Un saludo
Juan

Felipe Martínez D. dijo...

Hola Juan.

Prueba ésto:

Variable=$(cat /ruta/del/fichero/fichero.txt)

sed -i 's/Nacho/'$Variable'/g' *.txt


Aquí lo que se hace es sustituir "Nacho" por el valor de la variable.

En caso de que quieras hacer el caso contrario, sería así:

sed -i 's/'$Variable'/Nacho/g' *.txt

Espero que te sirva.

Saludos.

Anónimo dijo...

Para cambiar palabras de un archivo, con una palabra de otro archivo como sería?

Felipe Martínez D. dijo...

Hola.

Yo me haría un script, en el que primero se obtenga esa palabra del archivo y luego con el comando sed, como explico en este post, la sustituiría.

Aquí explico cómo leer un archivo de texto desde un script: http://felinfo.blogspot.com.es/2012/03/leer-un-archivo-de-texto-linea-por.html

Saludos.

Anónimo dijo...

esxelenteme quito muo trabajo de encima gracias buen post

Felipe Martínez D. dijo...

Me alegro de que te fuera de ayuda.

Saludos.

Anónimo dijo...

Hola, por favor me podrías ayudar con esta pregunta.

Tengo varios archivos en *.txt que tienen el siguiente formato:

00 00 01 +00.50 0
00 00 01 -00.46 0
00 00 01 +00.51 0
00 00 01 -00.48 0
00 00 01 +00.51 0
00 00 01 -00.48 0
00 00 01 9 0
00 00 01 +00.50 0
00 00 01 -00.46 0
00 00 01 +00.50 0
00 00 01 -00.46 0
00 00 01 -7 9 0
00 00 01 -00.48 0
00 00 01 +00.50 0
00 00 02 -00.46 0
00 00 02 +00.50 0
00 00 02 -00.46 0
00 00 02 +00.51 0
00 00 02 -00.48 0
00 00 02 -00.46 0
00 00 02 +00.50 0
00 00 02 -00.46 0
00 00 02 +00.51 0
00 00 02 -00.48 0
00 00 02 9 0
00 00 03 +00.50 0
00 00 03 -00.46 0
00 00 03 -7 9 0
00 00 03 +00.50 0
00 00 03 -00.46 0
00 00 03 -00.48 0
00 00 04 +00.50 0
00 00 04 -00.46 0

Hay alguna forma de poder hacer de que me borre las filas que no están completas. Algo así cómo por ejemplo de q me lea las columnas y si alguna fila no tiene las columnas completas me la elimina?

Felipe Martínez D. dijo...

Hola.

Por favor, explica mejor a qué te refieres cuando dices a que no tiene columnas completas. Pon un ejemplo e intentaré ayudarte.

Saludos.

Anónimo dijo...

Hola, Muchas gracias por la respuesta!

Te explico mejor el problema. Tengo varios archivos *.txt con el siguiente formato:

00 00 01 00.51 0
00 00 01 00.48 0
00 00 01 00.51 0
00 00 01 00.48 0
00 00 01 9
00 00 01 00.50 0
00 00 01 00.46 0
00 00 01 00.50 0
00 00 01 00.46 0
00 00 01 3
00 00 01 00.48 0
00 00 01 00.50 0
00 00 02 00.48 0
00 00 02 00.46 0
00 00 02 9 1
00 00 03 00.50 0
00 00 03 00.46 0
00 00 03
00 00 03 00.50 0
00 00 03 00.46 0
00 00 03 00.48 0

Entonces lo que yo deseo es que por medio de alguna rutina o algún comando en linux (nosé si en este caso se pueda utilizar los comandos sed o awk) me pueda generar lo siguiente:

00 00 01 00.51 0
00 00 01 00.48 0
00 00 01 00.51 0
00 00 01 00.48 0
00 00 01 00.50 0
00 00 01 00.46 0
00 00 01 00.50 0
00 00 01 00.46 0
00 00 01 00.48 0
00 00 01 00.50 0
00 00 02 00.48 0
00 00 02 00.46 0
00 00 03 00.50 0
00 00 03 00.46 0
00 00 03 00.50 0
00 00 03 00.46 0
00 00 03 00.48 0

Gracias por el tiempo.

Saludos,

José

Felipe Martínez D. dijo...

Hola José.

Prueba ésto, yo lo he probado con tus datos y ha funcionado. El nuevo archivo generado es nuevoarchivo.

awk 'length>15' miarchivo > nuevoarchivo


Saludos.

Anónimo dijo...

Hola Felipe,
Primero que nada mis más sinceras disculpas por este largo tiempo sin responder.
Muchas gracias por tu ayuda, funciona a la perfección.

Una pregunta adicional, si deseo realizar el mismo procedimiento para varios archivos a la vez cómo podría hacerlo? además quisiera que me lo guardara con el mismo nombre del archivo.

Bueno, nuevamente muchas gracias por tu tiempo!!

Saludos,

José

Felipe Martínez D. dijo...

Hola Jose.

Aquí hablan de usar awk para procesar varios archivos: http://stackoverflow.com/questions/14984340/using-awk-to-process-input-from-multiple-files

Si quieres guardarlo con el mismo nombre del archivo, te recomiendo que te crees un script. En ese script el resultado de awk debe guardarlo en un archivo auxiliar y posteriormente renombrar el archivo auxiliar al nombre del archivo de entrada (sobrescribiéndolo). Habría que hacerlo así ya que no es una buena idea procesar y escribir simultáneamente sobre un mismo archivo.

Saludos cordiales.

Anónimo dijo...

Muchas gracias por tu respuesta Felipe...intentaré hacerlo.

Unknown dijo...

Hola Jose.

ojala me puedas ayudar.

tengo un script del cual consulto a una BD mediante query. como resultado me da una URL
pero esta tiene en sierta posicion numeros de moviles Ejemplo:

#moviles:
movilA=56975183987
movilB=56998960000
movilC=56990726289
movilD=56990939648
movilF=56990939648
movilG=56978991023
movilH=56994799305


URLQuery=http://{{nodo3:17090/packmanager/v1/msisdns/{{movilC}}/packs?platform=SGA


Necesito que el resultado

me arroje:

URLQuery=http://{{nodo3:17090/packmanager/v1/msisdns/56990726289/packs?platform=SGA


otro ejemplo en la query de consulta me puede arrojar que en la url el movil se encuentre en otra posicion

url=http://fppdev:17018/portal/v1/client/{{movilD}}/bonuses

como resultado seria:
http://fppdev:17018/portal/v1/client/56990939648/bonuses


Gracias por tu tiempo.

Saludos.

Felipe Martínez D. dijo...

Hola.

Te recomiendo que leas tu archivo línea por línea como explico aquí: http://felinfo.blogspot.com.es/2012/03/leer-un-archivo-de-texto-linea-por.html .

Cuando leas una línea, guarda el número en una variable y posteriormente sustituye {{movilC}} por el valor de esa variable, usando sed y siguiendo el siguiente patrón:

sed -i 's/palabra-vieja/palabra-nueva/g' *.txt


Saludos.

Anónimo dijo...

hola felipe
por favor necesito de tu ayuda
necesito crear una gran cantidad de archivos de texto con el siguiente contenido

receptor = model1.pdbqt
ligand = 1.pdbqt

center_x = 0.0
center_y = 0.0
center_z = 0.0

size_x = 38
size_y = 28
size_z = 56

out = result_model01_01_01.pdbqt
log = result_model01_01_01.log

num_modes = 10

ahora necesito que se creen por lotes de un numero determinado que en el script que intento crear lo determino a priori, luego necesito que varie el ultimo numero para cada archivo de salida (o sea, para el out y log )
gracias de antemano

Felipe Martínez D. dijo...

Hola.

No he entendido bien lo que quieres hacer. ¿Lo que quieres que varíe es el nombre del archivo o el valor que se le asigna a las variables out o log?.

Unknown dijo...

Buenas tardes
Tengo varias carpetas numeradas sucesivamente como
folder-1 folder-2 folder-3 y ....así hasta folder-274
Cada una de ellas contiene un fichero llamado U
Este fichero U contiene la palabra velocidad
A parte tengo un fichero datos.csv en que en cada celda
A1 A2 A3.......hasta A274 hay un valor .
Quisiera saber como puedo modificar la palabra velocidad
por cada valor del fichero datos.csv respectivamente.
folder-1/U/velocidad=A1
...
Gracias de antemano
Simón

Unknown dijo...

He hecho este script pero sólo me cambia el fichero en la carpeta folder-1
#!/bin/sh
# Source tutorial run functions
#. $WM_PROJECT_DIR/bin/tools/RunFunctions

#!/bin/sh
cd ${0%/*} || exit 1 # run from this directory



i=1;
for w in `cat datos.csv`;do
echo "folder-$i/0/U";
sed "s/velxxxvel/$w/g" folder-$i/0/U >> folder-$i/0/U_new;
rm -rf folder-$i/0/U;
mv folder-$i/0/U_new folder-$i/0/U;
i=$[ $i + 1 ];
done

Felipe Martínez D. dijo...

Hola Simon.

No se si ésto lo solucionará porque no lo he probado, pero cambia la línea:

i=$[ $i + 1 ];

Por:

i=$((i+1));



A ver si de ese modo hace los cambios en el resto de carpetas.

Saludos.

Agustín Alberto Meriño Caro dijo...

Muy buen blog, era justo lo que necesitaba voy a probarlo.

Felipe Martínez D. dijo...

Muchas Gracias.

Un saludo.

DAJ dijo...

Saludos Felipe
Necesito sustituir todo el contenido de una linea en un fichero, por otro texto, sin importar el contenido de la misma.

Puedes sugerirme una solución???

DAJ dijo...

Gracias ya encontr'e una soluci'on...
Saludos

Felipe Martínez D. dijo...

Me alegro de que encontraras la solución.

Un saludo.

Pintochampion dijo...

Hola muy buenas. Necesito un script que dado un fichero con varias líneas lo copié en otro fichero varias veces. Además necesito reemplazar algunos caracteres.
Ejemplo:
Fichero:
Linea 1
Linea 2 XXX
Linea 3
Linea 4 XXX
Se necesita copiar Fichero a FSalida 4veces pero reemplazando XXX por el número de la repetición. Es decir 001 en la primera copia, 002 en la segunda. Puedes ayudarme? Gracias.

Felipe Martínez D. dijo...

Hola Pintochampion.

Muéstrame tu script y qué es lo que te falla. Yo intentaré ayudarte.

Saludos.

Tecnico dijo...

Hola quieria un script que haga lo siguente:

una carpeta con varias carpetas y en cada carpeta varios archivos de varias extensiones como .txt,.html,.php,.css,.js,. y mass.

Primero que buscar y reemplazar contenido como ejemplo admin por administrador , despues renombrar cincidencias en el nombre de los archivos ( todo que contenga ) por ejemplo (page) por (pagina) y al final cambiar nombre de carpeta donde encuentra cincidencias por ejemplo (img) por (imagenes). Les agradezgo mucjo de doy con la solucion que uso notepad++ y un renombrador de archivos y se tarda horas para cargar los archivos ( unos 12000 y pesan mas de 500Mb)

Felipe Martínez D. dijo...

Hola Popu.

Por favor, especifica un poco tu pregunta e intentaré ayudarte.

Saludos.

Unknown dijo...

Hola amigo tengo el caso que tengo archivo con extension a.jlm hasta j.jlm y necesito cambiar a.jlm hasta j.jlm por diferentes extensiones que tengo en un archivo denominado a.txt b.xls c.jpg hasta j.algo.
tengo los archivos y corte con
archivo=$(ls *jlm|cut -d "." -f 1)
archivo2=$(cat cambios.txt|cut -d "." -f 2)
//APARTIR DE AQUI NO SE QUE HACER, ESTA ERA MI IDEA PERO OBVIAMENTE NO RESULTA// el echo es para ver que resulte, despues lo cambiaria por un mv
for i in $archivo
do
for j in $archivo2
do
echo $i.$j
done
done

Gracias en verdad, buenas noches :)

Felipe Martínez D. dijo...

Hola.

No me queda claro lo que quieres hacer. De todos modos, en este post se explica como reemplazar el texto de varios archivos. Si quieres renombrar archivos masivamente te recomiendo leer éste otro: http://felinfo.blogspot.com.es/2010/12/renombrar-archivos-masivamente-en-linux.html

Saludos.

Unknown dijo...

Me salvaste la vida, 200 archivos eran :)

Felipe Martínez D. dijo...

Me alegro!. Un saludo.

Publicar un comentario

Felinfo: Java, Linux, Virtualización. Open Source.  ©Template Blogger Green by Dicas Blogger .

TOPO