Buscar y reemplazar texto dentro de un archivo mediante comandos

¿Cómo puedo encontrar y reemplazar palabras específicas en un archivo de texto mediante la línea de comandos?

sed -i 's/original/new/g' file.txt

Explicacion:

  • sed = Editor de secuencias
  • -i = in situ (es decir, guardar de nuevo en el archivo original)
  • La cadena de comandos:

    • s = el comando sustituto
    • original = una expresión regular que describe la palabra a reemplazar (o solo la palabra en sí)
    • new = el texto por el que se reemplazará
    • g = global (es decir, reemplaza todo y no solo la primera aparición)
  • file.txt = el nombre del archivo

Hay multitud de formas de lograrlo. Dependiendo de la complejidad de lo que se intenta lograr con el reemplazo de cadenas, 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 simple input.txt archivo, que puede usar para probar todos los ejemplos proporcionados aquí. El contenido del archivo:

roses are red , violets are blueThis is an input.txt and this doesn't rhyme

BASH

Bash no es realmente para el procesamiento de texto, pero se pueden hacer sustituciones simples a través de expansión de parámetros , en particular aquí podemos usar una estructura simple ${parameter/old_string/new_string}.

#!/bin/bashwhile IFS= read -r linedo    case "$line" in       *blue*) printf "%s\n" "${line/blue/azure}" ;;       *) printf "%s\n" "$line" ;;    esacdone < input.txt

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 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 usa, es básicamente la forma en que shell lee el archivo línea por línea. Ver este para 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() y gsub(). El primero solo reemplaza la primera ocurrencia, mientras que el segundo reemplaza las ocurrencias en toda la cadena. Por ejemplo, si tenemos string 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 hace 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 en el lugar, por lo tanto, la práctica habitual es guardar y reemplazar texto nuevo. Por ejemplo algo como esto:

awk '{sub(/blue/,"azure")}1' input.txt > temp.txt && mv temp.txt input.txt

SED

Sed es un editor de líneas. También usa expresiones regulares, pero para sustituciones simples es suficiente hacer:

sed 's/blue/azure/' input.txt

Lo bueno de esta herramienta es que tiene edición en el lugar, que puede habilitar con -i bandera.

Perl

Perl es otra herramienta que se usa a menudo para el procesamiento de textos, 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 de la siguiente manera:

perl -pe 's/blue/azure/' input.txt

Al igual que sed, perl también tiene la bandera-i.

Pitón

Este lenguaje es muy versátil y también se utiliza en una amplia 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 la siguiente:

python -c "import sys;lines=sys.stdin.read();print lines.replace('blue','azure')" < input.txt

Con Python, sin embargo , también necesita generar un nuevo archivo, lo que también puede hacer desde el propio script. Por ejemplo, aquí hay uno simple:

#!/usr/bin/env pythonimport sysimport osimport tempfiletmp=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 línea de comandos. El comando exacto para ejecutar un script de Python con un argumento de 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, por primera vez, asegúrese de que esté configurado como ejecutable con chmod +x ./myscript.py

Python también puede tener expresiones regulares, en particular, hay re módulo, que tiene re.sub() función, que se puede utilizar para reemplazos más avanzados.

Hay un número de maneras 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:

marco@imacs-suck: ~$ echo "The slow brown unicorn jumped over the hyper sleeping dog" > orlymarco@imacs-suck: ~$ sed s/slow/quick/ < orly > yarlymarco@imacs-suck: ~$ cat yarlyThe quick brown unicorn jumped over the hyper sleeping dog

Otra forma que puede tener más sentido que < strin y > strout es con pipas!

marco@imacs-suck: ~$ cat yarly | sed s/unicorn/fox/ | sed s/hyper/lazy/ > nowaimarco@imacs-suck: ~$ cat nowai The quick brown fox jumped over the lazy sleeping dog

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 reemplazan por 0, independientemente de la columna en la que se encuentre.


Si desea hacer un reemplazo en una columna específica, haga esto,

awk '{gsub(/pattern/,"replacement",column_number)}' file

Ejemplo:

awk '{gsub(/1/,"0",$1);}' file

Reemplaza 1 con 0 solo en la primera columna.

A Través de Perl,

$ echo 'foo' | perl -pe 's/foo/bar/g'bar

Puede usar Vim en modo Ex:

ex -s -c '%s/OLD/NEW/g|x' file
  1. % seleccionar todas las líneas

  2. s sustituir

  3. g reemplace todas las instancias en cada línea

  4. x escriba si se han realizado cambios (lo han hecho) y salga

sed es el stremas eréctilitor, en el que se puede utilizar | (pipe) para enviar flujos estándar (STDIN y STDOUT específicamente) a través de sed y alterarlos programáticamente sobre la marcha, lo que lo convierte en una herramienta útil en la tradición de la filosofía Unix; pero también puede editar archivos directamente, utilizando el -i parámetro mencionado a continuación.
Considere lo siguiente:

sed -i -e 's/few/asd/g' hello.txt

s/ se utiliza para ssustituir la expresión encontrada few con asd:

Los pocos, los valientes.


El TEA, el valiente.

/g significa "global", lo que significa hacer esto para toda la línea. Si dejas de lado el /g (con s/few/asd/, siempre debe haber tres barras diagonales sin importar qué) y few aparece dos veces en la misma línea, solo la primera few se cambia a asd:

Los pocos hombres, las pocas mujeres, los valientes.


Los hombres con TEA, las pocas mujeres, los valientes.

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 dejan intacta una desigualdad algebraica entrecomillada más adelante en la línea), pero en su ejemplo, donde especifica que dondequiera few si debe reemplazarse, asegúrese de tener eso /g.

Las siguientes dos opciones (banderas) se combinan en una, -ie:

-i la opción se utiliza para editar in colocar en el archivo hello.txt.

-e la opción indica el expression / comando para ejecutar, en este caso s/.

Nota: Es importante que utilice -i -e para buscar/reemplazar. Si lo haces -ie, crea una copia de seguridad de cada archivo con la letra 'e' adjunta.

Puedes hacer esto:

locate <part of filaname to locate> | xargs sed -i -e "s/<Old text>/<new text>/g" 

Ejemplos: para reemplazar todas las ocurrencias [logdir',"] (sin [] ) con [logdir',".getcwd ()] en todos los archivos que son resultado del comando locate, haga:

ex1:

locate tensorboard/program.py | xargs sed -i -e "s/old_text/NewText/g"

ex2:

locate tensorboard/program.py | xargs sed -i -e "s/logdir', ''/logdir', os.getcwd()/g"

donde [tensorboard/program.py] es el archivo a buscar