¿Cómo puedo encontrar y reemplazar palabras específicas en un archivo de texto usando la línea de comandos?
command-line
text-processing
Jon Doe
fuente
fuente
Respuestas:
Explicación:
sed
= Stream EDitor-i
= in situ (es decir, guardar de nuevo en el archivo original)La cadena de comando:
s
= el comando sustitutooriginal
= una expresión regular que describe la palabra a reemplazar (o solo la palabra misma)new
= el texto para reemplazarlo cong
= global (es decir, reemplazar todo y no solo la primera aparición)file.txt
= el nombre del archivofuente
sed
coincidirán con ellos. Agregue una-r
bandera si desea usar RE extendidos en su lugar./
carácter que necesita hacer coincidir, puede usar algún otro carácter como separador (por ejemplo's_old/text_new/text_g'
). De lo contrario, puede poner un\
antes de cualquiera$ * . [ \ ^
para obtener el carácter literal.sed -i '.bak' 's/original/new/g' file.txt
también se puede ejecutar con una extensión de longitud cerosed -i '' 's/original/new/g' file.txt
, que no generará respaldo.Hay varias formas diferentes de hacer esto. Uno está usando
sed
y Regex. SED es un editor de secuencias para filtrar y transformar texto. Un ejemplo es el siguiente:¡Otra forma que puede tener más sentido que
< strin
y> strout
es con tuberías!fuente
cat
encat file | sed '...'
cuenta que no es necesario. Puedes decir directamentesed '...' file
.sed -i'.bak' -e 's/unicorn/fox/g;s/hyper/brown/g' yarly
tomará el archivo yarly y hará los 2 cambios en el lugar mientras realiza una copia de seguridad. Usando eltime bash -c "$COMMAND"
tiempo sugiere que esta versión es ~ 5 veces más rápida.Hay muchas formas de lograrlo. Dependiendo de la complejidad de lo que uno intente lograr con el reemplazo de la cadena, y dependiendo de las herramientas con las que el usuario esté familiarizado, algunos métodos pueden preferirse más que otros.
En esta respuesta estoy usando un
input.txt
archivo simple , que puede usar para probar todos los ejemplos proporcionados aquí. El contenido del archivo:GOLPETAZO
Bash no está realmente destinado al procesamiento de texto, pero se pueden hacer sustituciones simples mediante la expansión de parámetros , en particular aquí podemos usar una estructura simple
${parameter/old_string/new_string}
.Este pequeño script no reemplaza en el lugar, lo que significa que tendría que guardar el texto nuevo en un archivo nuevo y deshacerse del archivo anterior, o
mv new.txt old.txt
Nota al margen: si tiene curiosidad sobre por qué
while IFS= read -r ; do ... done < input.txt
se usa, es básicamente la forma en que Shell lee el archivo línea por línea. Vea esto como referencia.AWK
AWK, al ser una utilidad de procesamiento de texto, es bastante apropiado para tal tarea. Puede hacer reemplazos simples y mucho más avanzados basados en expresiones regulares . Proporciona dos funciones:
sub()
ygsub()
. El primero solo reemplaza solo la primera ocurrencia, mientras que el segundo reemplaza las ocurrencias en toda la cadena. Por ejemplo, si tenemos una cadenaone potato two potato
, este sería el resultado:AWK puede tomar un archivo de entrada como argumento, por lo
input.txt
que sería fácil hacer lo mismo con :Dependiendo de la versión de AWK que tenga, puede o no tener edición en el lugar, por lo tanto, la práctica habitual es guardar y reemplazar texto nuevo. Por ejemplo algo como esto:
SED
Sed es un editor de línea. También usa expresiones regulares, pero para sustituciones simples es suficiente:
Lo bueno de esta herramienta es que tiene edición en el lugar, que puede habilitar con la
-i
bandera.Perl
Perl es otra herramienta que a menudo se usa para el procesamiento de texto, pero es un lenguaje de propósito general y se usa en redes, administración de sistemas, aplicaciones de escritorio y muchos otros lugares. Tomó prestados muchos conceptos / características de otros lenguajes como C, sed, awk y otros. La sustitución simple se puede hacer así:
Al igual que sed, perl también tiene la bandera -i.
Pitón
Este lenguaje es muy versátil y también se usa en una amplia variedad de aplicaciones. Tiene muchas funciones para trabajar con cadenas, entre las cuales está
replace()
, por lo que si tiene variables comovar="Hello World"
, podría hacervar.replace("Hello","Good Morning")
La manera simple de leer el archivo y reemplazar la cadena sería:
Con Python, sin embargo, también necesita generar un archivo nuevo, lo que también puede hacer desde el script. Por ejemplo, aquí hay uno simple:
Este script se llamará
input.txt
como argumento de línea de comandos. El comando exacto para ejecutar el script de Python con el argumento de la línea de comandos seríao
Por supuesto, asegúrese de que
./myscript.py
esté en su directorio de trabajo actual y, por primera vez, asegúrese de que esté configurado como ejecutable conchmod +x ./myscript.py
Python también puede tener expresiones regulares, en particular, hay un
re
módulo, que tiene unare.sub()
función, que se puede usar para reemplazos más avanzados.fuente
tr
comando en Unixtr
es otra gran herramienta, pero tenga en cuenta que es para reemplazar conjuntos de caracteres (por ejemplo,tr abc cde
se traduciríaa
ac
,b
ad
. Es un poco diferente de reemplazar palabras enteras comosed
opython
Puede usar Vim en modo Ex:
%
seleccione todas las líneass
sustituirg
reemplazar todas las instancias en cada líneax
escriba si se han realizado cambios (ellos sí) y salgafuente
A través del comando gsub de awk,
Ejemplo:
En el ejemplo anterior, todos los 1 se reemplazan por 0 independientemente de la columna donde se encuentra.
Si desea hacer un reemplazo en una columna específica, haga lo siguiente,
Ejemplo:
Reemplaza 1 con 0 solo en la primera columna.
A través de Perl,
fuente
inotifywait
undersh
env e informando datos en formato CSV (porque el formato personalizado tiene errores). Entonces pensé que no hay una manera simple de manejar documentos CSV en scripts de shell ... Y lo quiero muy ligero. Entonces comencé un script bastante simple para analizar e informar CSV. Leí las especificaciones de CSV y noté que está más elaborado de lo que esperaba y admite valores multilínea entre comillas dobles. Estaba confiando en lased
tokenización, pero pronto me di cuenta de que incluso lo quesed
llaman multilíneas es de hasta dos líneas. ¿Qué sucede si uno de mis valores CSV abarca más de dos líneas?sed
es el s TREAM ed itor , en el que se puede utilizar|
(tubería) para enviar flujos estándares (entrada y salida estándar específicamente) a travéssed
y modificarlos mediante programación sobre la marcha, por lo que es una herramienta muy útil en la filosofía de la tradición Unix; pero también puede editar archivos directamente, utilizando el-i
parámetro mencionado a continuación.Considere lo siguiente :
s/
se utiliza para s ubstitute la expresión que se encuentrafew
conasd
:/g
significa "global", lo que significa hacer esto para toda la línea. Si deja de lado/g
(cons/few/asd/
, siempre debe haber tres barras sin importar qué) yfew
aparece dos veces en la misma línea, solo la primerafew
se cambia aasd
:Esto es útil en algunas circunstancias, como alterar caracteres especiales al comienzo de las líneas (por ejemplo, reemplazar los símbolos mayores que algunas personas usan para citar material anterior en hilos de correo electrónico con una pestaña horizontal mientras deja una desigualdad algebraica citada más adelante en la línea intacto), pero en su ejemplo donde especifica que en cualquier
few
lugar se debe reemplazar, asegúrese de tenerlo/g
.Las siguientes dos opciones (banderas) se combinan en una sola
-ie
:-i
opción se utiliza para editar i n coloco en el archivohello.txt
.-e
opción indica el correo Xpression / comando para ejecutar, en este casos/
.Nota: es importante que utilice
-i -e
para buscar / reemplazar. Si lo hace-ie
, crea una copia de seguridad de cada archivo con la letra 'e' añadida.fuente
Puedes hacer así:
Ejemplos: para reemplazar todas las ocurrencias [logdir ',' '] (sin []) con [logdir', os.getcwd ()] en todos los archivos que son el resultado del comando de localización, haga lo siguiente:
ex1:
ex2:
donde [tensorboard / program.py] es el archivo para buscar
fuente
logdir', ''
->/logdir', os.getcwd()
) hace que esta respuesta sea difícil de analizar. Además, vale la pena especificar que su respuesta primero localiza los archivos para usar sed, porque no es parte de la pregunta.