Si queremos buscar y reemplazar texto en entornos Linux, disponemos de varias herramientas para ello.
Una de ellas es con el comando sed.
El comando sed está presente en la mayoría de distribuciones de Linux y está pensado para manipular cadenas de texto.
Si no disponemos del comando sed lo podemos instalar de la siguiente forma:
- Para CentOS/RHEL: yum install sed
- Para Debian/Ubuntu: apt-get install sed
Sintaxis general y tres ejemplos para reemplazar texto en archivos:
Sintaxis general:
sed -i 's/texto-a-buscar/texto-a-reemplazar/g' "Fichero o directorio"
Ejemplo 1: Cambiamos el texto Sysadmit por SYSADMIT del interior del fichero: test.txt
[root@LINUX1 test]# cat test.txt
Sysadmit1
1Sysadmit
90Sysadmit82
HSysadmitH21
Sysadmit1
1Sysadmit
90Sysadmit82
HSysadmitH21
[root@LINUX1 test]# sed -i 's/Sysadmit/SYSADMIT/g' "test.txt"
[root@LINUX1 test]# cat test.txt
SYSADMIT1
1SYSADMIT
90SYSADMIT82
HSYSADMITH21
SYSADMIT1
1SYSADMIT
90SYSADMIT82
HSYSADMITH21
Ejemplo 2: Cambiamos el texto SYSADMIT por --SYSADMIT-- en todos los ficheros *.txt a partir de la ruta /test/ de forma recursiva.
Para ello utilizaremos los siguientes comandos:
find: Nos realizará una búsqueda de todos los ficheros según el patrón definido.
xargs: Ejecutará un comando (en este caso sed) para cada resultado generado por el comando find.
| : Pipe o tubería, en este caso la salida de find corresponderá a la entrada de sed.
| : Pipe o tubería, en este caso la salida de find corresponderá a la entrada de sed.
sed: Realizará el "buscar-reemplazar".
/test
[root@LINUX1 test]# du -ah
4.0K ./new/test.txt
8.0K ./new
4.0K ./test.txt
16K .
[root@LINUX1 test]# cat ./new/test.txt
SYSADMIT1
1SYSADMIT
90SYSADMIT82
HSYSADMITH21
[root@LINUX1 test]# cat ./test.txt
SYSADMIT1
1SYSADMIT
90SYSADMIT82
HSYSADMITH21
[root@LINUX1 test]# find /test/ -name "*.txt" -print | xargs sed -i "s/SYSADMIT/--SYSADMIT--/g"
[root@LINUX1 test]# cat ./new/test.txt
--SYSADMIT--1
1--SYSADMIT--
90--SYSADMIT--82
H--SYSADMIT--H21
[root@LINUX1 test]# cat ./test.txt
--SYSADMIT--1
1--SYSADMIT--
90--SYSADMIT--82
H--SYSADMIT--H21
Ejemplo 3: Cambiamos una URL por otra del interior de un fichero de texto (test.txt).
El problema de las URLs es que contienen el carácter: "/".
El carácter "/", sed lo utiliza para definir el texto original y el texto a reemplazar.
En el siguiente ejemplo, reemplazaremos la URL:
http://sysadmit.com
por:
http://www.sysadmit.com/p/faq-libros.html
dentro del fichero: test.txt
Para ello, utilizaremos el caracter: "%"
[root@LINUX1 test]# cat test.txt
http://sysadmit.com
[root@LINUX1 test]# sed -i "s%http://sysadmit.com%http://www.sysadmit.com/p/faq-libros.html%g" "test.txt"
[root@LINUX1 test]# cat test.txt
http://www.sysadmit.com/p/faq-libros.html
Gracias!.
ResponderEliminarBuen tutorial!.
Saludos,
¡Gracias a ti! ¡Me alegro que te haya gustado!
EliminarUn saludo,
Xavi.
Excelente!!!, tengo un problema, necesito reemplazar solo una vez en el archivo (la primera vez)
ResponderEliminarMe explico, para el caso del ejemplo, si el archivo fuera
Sysadmit
Sysadmit
Sysadmit
después de ejecutar el comando que indicas (sed -i 's/Sysadmit/SYSADMIT/g' "test.txt") quedaría:
SYSADMIT
SYSADMIT
SYSADMIT
Pero yo necesito que quede:
SYSADMIT
Sysadmit
Sysadmit
¿es posible hacer eso?
Hola Andrés,
EliminarAquí tienes como hacerlo:
[root@LINUX1]# cat test.txt
Sysadmit
Sysadmit
Sysadmit
[root@LINUX1]# sed -i '0,/Sysadmit/ s//SYSADMIT/' "test.txt"
[root@LINUX1]# cat test.txt
SYSADMIT
Sysadmit
Sysadmit
¡¡Un saludo!!
Xavi.
Xavi,
Eliminares justo lo que necesitaba.
muchas gracias!.
¡Gracias a ti!
Eliminar¡Un saludo!
Xavi.
Hola! Necesito hacer sed s/patron1/patron2/g file.txt > filefinal. El tema es que patron 1 y patron 2 corresponden a col 1 y col 2 de otro archivo (index.txt). Cómo hago referencia a esas columnas y cómo le pido que repita el procedimiento desde la primer hasta la última fila? Gracias!
ResponderEliminarHola Matias,
EliminarLo puedes hacer con este comando: sed s/`cat index.txt|awk '{ print $1 }'`/`cat index.txt |awk '{ print $2 }'`/g file.txt > final.txt
el secreto está en dónde hay patrón1 / patrón2 ejecutar un comando de awk: `cat index.txt|awk '{ print $1 }'`
Ejemplo para probarlo:
[root@SYSADMIT.LAB 2]# ls
file.txt index.txt
[root@SYSADMIT.LAB 2]# cat index.txt
Columna1 Columna2
[root@SYSADMIT.LAB 2]# cat file.txt
Columna1
Columna1
Columna1
Columna1
Columna1
Columna1
Columna1
Columna1
[root@SYSADMIT.LAB 2]# sed s/`cat index.txt|awk '{ print $1 }'`/`cat index.txt |awk '{ print $2 }'`/g file.txt
Columna2
Columna2
Columna2
Columna2
Columna2
Columna2
Columna2
Columna2
[root@SYSADMIT.LAB 2]# sed s/`cat index.txt|awk '{ print $1 }'`/`cat index.txt |awk '{ print $2 }'`/g file.txt > final.txt
[root@SYSADMIT.LAB 2]# cat final.txt
Columna2
Columna2
Columna2
Columna2
Columna2
Columna2
Columna2
Columna2
Muy bueno, lo uso también en bash del macOS
ResponderEliminar¡Muchas gracias por tu comentario!
EliminarUn saludo,
Xavi.
Hola que tal tengo un problema necesito sustituir una cadena así:
ResponderEliminarexten => _77[0-9]00[1-6],1,MixMonitor(/home/site/${STRFTIME(${EPOCH},,%Y%m%d-%H%M%S)}-${EXTEN}-${CALLERID(num)}.wav)
y lo intento así:
sed -i "s%exten => _77[0-9]00[1-6],1,MixMonitor(/home/site/${STRFTIME(${EPOCH},,%Y%m%d-%H%M%S)}-${EXTEN}-${CALLERID(num)}.wav)%hola%g" "extensions001.conf"
Aqui en el ejemplo quiero sustituirlo por hola, pero enrealidad seria por:
exten => _77[0-9]00[1-6],1,MixMonitor(/home/site/cabina1/${STRFTIME(${EPOCH},,%Y%m%d-%H%M%S)}-${EXTEN}-${CALLERID(num)}.wav)
Pero cuando lo intento me dice:
-bash: s%exten => _77[0-9]00[1-6],1,MixMonitor(/home/site/${STRFTIME(${EPOCH},,%Y%m%d-%H%M%S)}-${EXTEN}-${CALLERID(num)}.wav)%hola%g: sustitución errónea
Podrias ayudarme ..... Saludos.
Hola! necesito sustituir
ResponderEliminarSYSADMIT
SYSADMIT
SYSADMIT
por
SYSADMIT1
SYSADMIT2
SYSADMIT3
Podrían ayudarme! Gracias!
Hola, Tengo un archivo con doble salto de linea \n\n y necesito que quede solo con un salto de linea, el archivo luce asi:
ResponderEliminar752
3165545715
225
680
Intente :
sed 's/\n\n/\n/g' archivo.txt
pero no funcionó
Incluso a pesar de que a primera vista no me resultó muy amigable para leer, lo leí y... ¡me pareció excelente!
ResponderEliminar¡Muchas gracias!
¡Gracias por tu comentario!
EliminarUn saludo,
Xavi.
Hola Quisiera pedirte apoyo. estoy ejecutando el sed
ResponderEliminarsed -i 's/'"("'/'"(Total = "'/g' archivo.txt
el archivo.txt fue creado por un usuario con mas privilegios y debo ejecutar la sentencia con un usuario de explotación.
el usuario de explotación funciona con archivos creados bajo su mismo usr, pero no me deja con los archivos creados con otro usuario.
Como se puede ejecutar para que lo realice igual?
El error que da: sed: cannot rename ./sedr2pm9K: Operation not permitted
el archivo esta con permisos 777 y la ruta donde esta el archivo tambien.
Hola,
Eliminar¿Tienes SELinux activado?
- Para verificar el estado de SELinux:
getenforce
- Para deshabilitar SELinux:
Editar el fichero: /etc/selinux/config
Configurar: SELINUX=disabled
Es necesario reiniciar el equipo para que se aplique la configuración.
Un saludo,
Xavi.
Muy buena guia Xavi.
ResponderEliminarUn saludo.
¡Gracias por tu comentario!
EliminarXavi.
Hola,
ResponderEliminarno sé como puedo reemplazar una palabra en común en varios archivos del fichero.
Ejemplo estaba en la versión 6 y dentro de esta carpeta todos los archivos apuntan a /v6/ejemplo y quiero hacer una copia del fichero version6 a version7 y que en version7 todos los archivos que apuntan a v6/ejemplo apunten a /v7/ejemplo
Hola,
EliminarCon el comando find puedes utilizar sed para reemplazar en varios ficheros.
En este mismo post tienes un ejemplo:
find /test/ -name "*.txt" -print | xargs sed -i "s/SYSADMIT/--SYSADMIT--/g"
Un saludo,
Xavi.
Hola, estoy intentando hacer un script que realice lo siguiente:
ResponderEliminarDado dos archivos
en archivo1 tengo:
[seccion1]
A=def
B=def
C=def
[seccion2]
A=def
B=def
[seccion3]
A=def
Y en el archivo2, tengo
[seccion1]
A=loc
B=loc
C=loc
[seccion2]
B=loc
Y me gustaría como objetivo final, tener el archivo2 modificado con esta forma
[seccion1]
A=loc
B=def
C=def
[seccion2]
A=def
B=loc
[seccion3]
A=def
Se me complica poder recorrer las secciones por indice y poder compararlas entre los archivos, además de que tengo que ver si tienen los mismos settings o distintos
La idea es que dados dos archivos de configuraciones, sobre escribir las cosas de uno en el otro con determinados criterios.
Si alguien puede ayudarme me vendría bien! gracias
Buenos días, necesito reemplazar el contenido entre dos etiquetas que no están en la misma linea de un XML, como lo puedo hacer?
ResponderEliminarLo he intentado con sed -i.BAK 's@\(<'parameterizedSpecification'>\).\+\(\)@\1'" TEXT1 \n TEXT2 \n "'\2@' /tmp/pepe.xml
pero solo funciona si el tag está en la misma linea.
Este es el ejemplo del XML
#https://en.wikipedia.org/wiki/Cron#CRON_expression
#REINICIO LOS LUNES A PETICION DE PROYECTO
#00 7 * * 1 % AUTOMATIC_RUN=true;BUILD_NUM=1;ENVIRON=$ENVIRON;ACTION=RESTART;SERVICE=ALL;REMOTEDEBUGMODE=true
Gracias
Mil gracias, muy bien explicado.
ResponderEliminar