GNU/Linux >> Tutoriales Linux >  >> Linux

¿Intercambiar limpiamente todas las ocurrencias de dos cadenas usando Sed?

Supongamos que tengo un archivo que contiene varias apariciones de StringA y StringB. Quiero reemplazar todas las apariciones de StringA con StringB y (simultáneamente) todas las apariciones de StringB con StringA.

En este momento, estoy haciendo algo como

cat file.txt | sed 's/StringB/StringC/g' | sed 's/StringA/StringB/g' | sed 's/StringC/StringA/g'

El problema con este enfoque es que asume que StringC no aparece en el archivo. Si bien esto no es un problema en la práctica, esta solución todavía se siente sucia, es decir, se siente como una oportunidad para aprender más magia de Unix. 🙂

Respuesta aceptada:

Si StringB y StringA no puede aparecer en la misma línea de entrada, entonces puede decirle a sed que realice el reemplazo de una manera, y solo intente de la otra manera si no hubo ocurrencias de la primera cadena buscada.

<file.txt sed -e 's/StringA/StringB/g' -e t -e 's/StringB/StringA/g'

En el caso general, no creo que haya un método fácil en sed. Por cierto, tenga en cuenta que la especificación es ambigua si StringA y StringB puede superponerse. Aquí hay una solución de Perl, que reemplaza la aparición más a la izquierda de cualquier cadena y se repite.

<file.txt perl -pe 'BEGIN {%r = ("StringA" => "StringB", "StringB" => "StringA")}
                    s/(StringA|StringB)/$r{$1}/ge'

Si desea seguir con las herramientas POSIX, awk es el camino a seguir. Awk no tiene un primitivo para reemplazos parametrizados generales, por lo que debe crear el suyo propio.

<file.txt awk '{
    while (match($0, /StringA|StringB/)) {
        printf "%s", substr($0, 1, RSTART-1);
        $0 = substr($0, RSTART);
        printf "%s", /^StringA/ ? "StringB" : "StringA";
        $0 = substr($0, 1+RLENGTH)
    }
    print
}'

Linux
  1. ¿Coincidencia de patrones multilínea usando Sed, Awk o Grep?

  2. ¿Eliminar todos los comentarios de C con Sed?

  3. ¿Usando una referencia a una variable de cadena Bash en Sed?

  4. ¿Usando Sed con caracteres especiales?

  5. ¿Proporcionar dos argumentos a una opción usando Getopts?

Cómo extender el espacio de intercambio usando el archivo de intercambio en Linux

¿Mostrar todo el archivo hasta el partido?

Qué proceso está usando todo mi disco IO

sed principiante:cambiar todas las ocurrencias en una carpeta

Usando sed para eliminar un bloque de texto

sed - cómo hacer grupos de expresiones regulares usando sed