¿Cómo puedo encontrar y reemplazar palabras específicas en un archivo de texto utilizando la línea de comandos?
¿Cómo se incorpora el regex con esto?
¿Cómo puedo encontrar y reemplazar palabras específicas en un archivo de texto utilizando la línea de comandos?
sed -i 's/original/new/g' file.txt
Explicación:
sed
= Stream EDitor-i
= in-place (es decir, guardar de nuevo en el archivo original)La cadena de comandos:
s
= el comando de sustituciónoriginal
= una expresión regular que describa la palabra a sustituir (o simplemente la palabra en sí)new
= el texto para sustituirlo porg
= global (es decir, reemplazar todo y no sólo la primera ocurrencia)file.txt
= el nombre del archivo
@Akiva Si incluye caracteres especiales regex en su búsqueda sed
los emparejará. Añade un -r
si desea utilizar los REs extendidos en su lugar.
¿Puedo utilizar el comando "sed -i" cuando las cadenas "original" y "nueva" contienen caracteres especiales como "/" o similares?
Hay multitud de formas de conseguirlo. Dependiendo de la complejidad de lo que se intente conseguir con el reemplazo de cadenas, y dependiendo de las herramientas con las que el usuario esté familiarizado, se pueden preferir unos métodos más que otros.
En esta respuesta, estoy usando un simple input.txt
que puede utilizar para probar todos los ejemplos que se ofrecen aquí. El contenido del archivo:
roses are red , violets are blue
This is an input.txt and this doesn't rhyme
Bash no está pensado para procesar texto, pero se pueden hacer sustituciones sencillas mediante expansión de parámetros En particular, aquí podemos utilizar una estructura simple ${parameter/old_string/new_string}
.
#!/bin/bash
while IFS= read -r line
do
case "$line" in
*blue*) printf "%s\n" "${line/blue/azure}" ;;
*) printf "%s\n" "$line" ;;
esac
done < input.txt
Este pequeño script no hace el reemplazo en el lugar, lo que significa que usted tendría que guardar el nuevo texto en el nuevo archivo, y deshacerse del archivo antiguo, o mv new.txt old.txt
Nota al margen: si tiene curiosidad por saber por qué while IFS= read -r ; do ... done < input.txt
se utiliza, es básicamente la manera de Shell de leer el archivo línea por línea. Ver este como referencia.
AWK, al ser una utilidad de procesamiento de texto, es bastante apropiada para esta tarea. Puede hacer reemplazos simples y otros mucho más avanzados basados en expresiones regulares . Ofrece dos funciones: sub()
y gsub()
. El primero sólo reemplaza la primera ocurrencia, mientras que el segundo - reemplaza las ocurrencias en toda la cadena. Por ejemplo, si tenemos la cadena one potato two potato
Este sería el resultado:
$ echo "one potato two potato" | awk '{gsub(/potato/,"banana")}1'
one banana two banana
$ echo "one potato two potato" | awk '{sub(/potato/,"banana")}1'
one banana two potato
AWK puede tomar un archivo de entrada como argumento, por lo que hacer lo mismo con input.txt
sería fácil:
awk '{sub(/blue/,"azure")}1' input.txt
Dependiendo de la versión de AWK que tenga, puede o no tener edición in situ, por lo que la práctica habitual es guardar y reemplazar el texto nuevo. Por ejemplo, algo como esto:
awk '{sub(/blue/,"azure")}1' input.txt > temp.txt && mv temp.txt input.txt
Sed es un editor de líneas. También utiliza expresiones regulares, pero para las sustituciones simples es suficiente para hacer:
sed 's/blue/azure/' input.txt
Lo bueno de esta herramienta es que tiene edición in situ, que puedes activar con -i
flag.
Perl es otra herramienta que se utiliza a menudo para el procesamiento de textos, pero es un lenguaje de propósito general, y se utiliza en redes, administración de sistemas, aplicaciones de escritorio, y muchos otros lugares. Ha tomado prestados muchos conceptos/características de otros lenguajes como C, sed, awk, y otros. La sustitución simple se puede hacer así:
perl -pe 's/blue/azure/' input.txt
Al igual que sed, perl también tiene la flag -i.
Este lenguaje es muy versátil y se utiliza en una gran variedad de aplicaciones. Tiene muchas funciones para trabajar con cadenas, entre las que se encuentra replace()
Así que si tienes una variable como var="Hello World"
, podrías hacer var.replace("Hello","Good Morning")
Una forma sencilla de leer el archivo y reemplazar la cadena en él sería así:
python -c "import sys;lines=sys.stdin.read();print lines.replace('blue','azure')" < input.txt
Con Python, sin embargo, también hay que dar salida a un nuevo archivo , lo que también se puede hacer desde el propio script. Por ejemplo, aquí hay uno sencillo:
#!/usr/bin/env python
import sys
import os
import tempfile
tmp=tempfile.mkstemp()
with open(sys.argv[1]) as fd1, open(tmp[1],'w') as fd2:
for line in fd1:
line = line.replace('blue','azure')
fd2.write(line)
os.rename(tmp[1],sys.argv[1])
Este script debe ser llamado con input.txt
como argumento de la línea de comandos. El comando exacto para ejecutar Python script con el argumento de la línea de comandos sería
$ ./myscript.py input.txt
o
$ python ./myscript.py input.txt
Por supuesto, asegúrese de que ./myscript.py
está en su directorio de trabajo actual y para la primera forma, asegúrese de que se establece como ejecutable con chmod +x ./myscript.py
Python también puede tener expresiones regulares, en particular, hay re
que tiene re.sub()
que puede utilizarse para sustituciones más avanzadas.
¡Buena recopilación! Otra forma posible que no se menciona aquí es utilizar el tr
comando en unix
Hay varias formas de hacerlo. Una de ellas es utilizar sed
y Regex. SED es un editor de flujos para filtrar y transformar texto. Un ejemplo es el siguiente:
marco@imacs-suck: ~$ echo "The slow brown unicorn jumped over the hyper sleeping dog" > orly
marco@imacs-suck: ~$ sed s/slow/quick/ < orly > yarly
marco@imacs-suck: ~$ cat yarly
The quick brown unicorn jumped over the hyper sleeping dog
Otra forma que puede tener más sentido que < strin
y > strout
¡es con tuberías!
marco@imacs-suck: ~$ cat yarly | sed s/unicorn/fox/ | sed s/hyper/lazy/ > nowai
marco@imacs-suck: ~$ cat nowai
The quick brown fox jumped over the lazy sleeping dog
nota la cat
en cat file | sed '...'
es innecesario. Puede decir directamente sed '...' file
.
A través del comando gsub de awk,
awk '{gsub(/pattern/,"replacement")}' file
Ejemplo:
awk '{gsub(/1/,"0");}' file
En el ejemplo anterior, todos los 1 se sustituyen por 0, independientemente de la columna en la que se encuentren.
Si quieres hacer un reemplazo en una columna específica, entonces haz lo siguiente,
awk '{gsub(/pattern/,"replacement",column_number)}' file
Ejemplo:
awk '{gsub(/1/,"0",$1);}' file
Sustituye el 1 por el 0 sólo en la primera columna.
A través de Perl,
$ echo 'foo' | perl -pe 's/foo/bar/g'
bar
EnMiMaquinaFunciona es una comunidad de administradores de sistemas en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros sysadmin, hacer tus propias preguntas o resolver las de los demás.