Encuentra y reemplaza texto dentro de un archivo usando comandos

433

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

    
pregunta Jon Doe 07.01.2011 - 05:10

7 respuestas

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

Explicación:

  • sed = Stream EDitor
  • -i = in situ (es decir, guardar de nuevo en el archivo original)
  • La cadena de comando:

    • s = el comando sustituto
    • original = una expresión regular que describe la palabra para reemplazar (o solo la palabra misma)
    • new = el texto para reemplazarlo con
    • g = global (es decir, reemplaza todo y no solo la primera vez)
  • file.txt = el nombre del archivo

respondido por el cscarney 07.01.2011 - 05:23
26

Hay varias formas diferentes de hacer esto. Uno está usando sed y Regex. SED es un editor de flujo 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 pipes!

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
    
respondido por el Marco Ceppi 07.01.2011 - 05:26
15

Puedes usar Vim en modo Ex:

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

  2. s substitute

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

  4. x escribe si se han realizado cambios (tienen) y sale

respondido por el Steven Penny 16.04.2016 - 20:36
14

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 donde se encuentre.

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

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

Ejemplo:

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

Reemplaza 1 con 0 en la columna 1 solamente.

a través de Perl,

$ echo 'foo' | perl -pe 's/foo/bar/g'
bar
    
respondido por el Avinash Raj 02.07.2014 - 14:59
12

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 un archivo simple input.txt , que puede usar para probar todos los ejemplos proporcionados 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 el procesamiento de texto, pero las sustituciones simples se pueden realizar a través de expansión de parámetros , en particular aquí podemos usar la 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 reemplaza in situ, lo que significa que debe guardar el texto nuevo en un archivo nuevo y deshacerse del archivo anterior, o mv new.txt old.txt

Nota: si tiene curiosidad acerca de por qué se usa while IFS= read -r ; do ... done < input.txt , básicamente es la forma en que Shell lee el archivo línea por línea. Consulte esto como referencia.

AWK

AWK, al ser una utilidad de procesamiento de texto, es bastante apropiado para esa tarea. Puede hacer reemplazos simples y muchos 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 una cadena completa. 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 hacer las mismas cosas con input.txt , sería fácil:

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

Dependiendo de la versión de AWK que tenga, puede que tenga o no edición in situ, por lo que 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ínea. También usa expresiones regulares, pero para sustituciones simples es suficiente:

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

Lo bueno de esta herramienta es que tiene edición in situ, que puede habilitar con el indicador -i .

Perl

Perl es otra herramienta que se utiliza a menudo para el procesamiento de texto, pero es un lenguaje de uso general y se usa en redes, administración de sistemas, aplicaciones de escritorio y en 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í:

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

Como sed, Perl también tiene la bandera -i.

Python

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() , así que si tienes una variable como var="Hello World" , podrías hacer var.replace("Hello","Good Morning")

Una forma simple de leer el archivo y reemplazar la cadena sería así:

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, que también puede hacer desde el propio script. Por ejemplo, aquí hay uno simple:

#!/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 invocarse con input.txt como argumento de línea de comandos.

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

    
respondido por el Sergiy Kolodyazhnyy 03.02.2017 - 08:49
6

sed es el s tream ed itor , en que puedes usar | (pipe) para enviar streams estándar (STDIN y STDOUT específicamente) a través de sed y modificarlos programáticamente en el volar, convirtiéndolo en una herramienta útil en la tradición filosófica de Unix; pero también puede editar archivos directamente, utilizando el parámetro -i mencionado a continuación.
Considere lo siguiente :

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

s/ se usa para s ubicar la expresión encontrada few con asd :

  

Los pocos, los valientes.

     

El asd, el valiente.

/g significa "global", lo que significa hacer esto para toda la línea. Si dejas fuera el /g (con s/few/asd/ , siempre tiene que haber tres barras, no importa qué) y few aparece dos veces en la misma línea, solo el primer few cambia a asd :

  

Los pocos hombres, las pocas mujeres, los valientes.

     

Los hombres asd, las pocas mujeres, los valientes.

Esto es útil en algunas circunstancias, como la alteración de caracteres especiales al comienzo de las líneas (por ejemplo, reemplazar los símbolos de mayor tamaño que algunas personas usan para citar material anterior en hilos de correo electrónico con una pestaña horizontal dejando una desigualdad algebraica más tarde) en la línea intacta), pero en su ejemplo donde especifica que en cualquier lugar few ocurre, debe reemplazarse, asegúrese de tener ese /g .

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

La opción

-i se usa para editar i en el archivo hello.txt .

La opción

-e indica el e comando xpression / para ejecutar, en este caso s/ .

Nota: es importante que use -i -e para buscar / reemplazar. Si hace -ie , crea una copia de seguridad de cada archivo con la letra 'e' adjuntada.

    
respondido por el Chaminda Bandara 23.11.2017 - 10:00
0

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', os.getcwd ()] en todos los archivos que son resultado del comando locate, haz:

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

donde [tensorboard / program.py] es un archivo para buscar

    
respondido por el Nguyễn Tuấn Anh 24.07.2018 - 04:13

Lea otras preguntas en las etiquetas