834 votos

Buscar y reemplazar texto dentro de un archivo mediante comandos

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

1336voto

Adam Haile Puntos 12576
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ón
    • original = una expresión regular que describa la palabra a sustituir (o simplemente la palabra en sí)
    • new = el texto para sustituirlo por
    • g = global (es decir, reemplazar todo y no sólo la primera ocurrencia)
  • file.txt = el nombre del archivo

0 votos

¿Cómo se incorpora el regex con esto?

3 votos

@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.

1 votos

¿Puedo utilizar el comando "sed -i" cuando las cadenas "original" y "nueva" contienen caracteres especiales como "/" o similares?

57voto

Serg Puntos 17677

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

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

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

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

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.

Python

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.

1 votos

¡Buena recopilación! Otra forma posible que no se menciona aquí es utilizar el tr comando en unix

1 votos

@TapajitDey Sí, tr es otra gran herramienta, pero tenga en cuenta que es para reemplazar conjuntos de caracteres ( por ejemplo tr abc cde traduciría a a c , b a d . Es un poco diferente de sustituir palabras enteras como con sed o python

37voto

Wulfbane Puntos 41

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

6 votos

nota la cat en cat file | sed '...' es innecesario. Puede decir directamente sed '...' file .

1 votos

De hecho, esto puede reducirse aún más: 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 hace una copia de seguridad. Usando time bash -c "$COMMAND" al tiempo sugiere que esta versión es un ~5 veces más rápida.

22voto

Avinash Raj Puntos 29074

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

22voto

Steven Penny Puntos 182

Puedes usar Vim en modo Ex:

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

  2. s sustituto

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

  4. x escribir si se han realizado cambios (lo han hecho) y salir

EnMiMaquinaFunciona.com

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.

Powered by:

X