¿Cómo se puede reemplazar una parte de una línea con sed?

La línea

DBSERVERNAME     xxx

debe ser reemplazado para:

DBSERVERNAME     yyy

El valor xxx puede variar y hay dos pestañas, entre dbservername y el valor. Este par nombre-valor es uno de los muchos de un archivo de configuración.

He probado con la siguiente referencia inversa:

echo "DBSERVERNAME    xxx" | sed -rne 's/\(dbservername\)[[:blank:]]+\([[:alpha:]]+\)/ yyy/gip'

y que resultó en un error: invalid referencia \1 `s’ del comando de RHS.

Qué hay de malo con la expresión? El uso de GNU sed.

InformationsquelleAutor calvinkrishy | 2009-07-02

7 Comentarios

  1. 45

    Esto funciona:

    sed -rne 's/(dbservername)\s+\w+/ yyy/gip'
    

    (Cuando se utiliza la opción-r, usted no tiene que salir de los paréntesis.)

    Poco de explicación:

    • -r está expresiones regulares extendidas – hace una diferencia en cómo la expresión regular que está escrito.
    • -n no impresión a menos que se especifique – sed imprime por defecto, de lo contrario,
    • -e significa que lo que sigue es una expresión. Vamos a romper la expresión de abajo:
      • s/// es el comando para buscar y reemplazar, y lo que está entre el primer par es la expresión regex partido, y el segundo par de la sustitución,
      • gip, que sigue la búsqueda de comando reemplazar; g medio global, es decir, cada partido, en vez de sólo la primera será reemplazado en una línea; i es el caso de insensibilidad; p medios de impresión cuando de hecho (recordar el -n bandera de antes!),
      • Los corchetes representan una coincidencia parte, que llegará más tarde. Así dbservername es el primer partido que se parte,
      • \s es el espacio en blanco, + se refiere a uno o más (vs *, cero o más ocurrencias,
      • \w es una palabra, que es cualquier letra, dígito o carácter de subrayado,
      • \1 es una expresión especial para GNU sed que imprime el primer partido entre corchetes en el acompañamiento de búsqueda.
    • Yo sé que ustedes tienen un montón de experiencia en el shell de comandos…pero por favor, cuidado con los aspirantes linux noobs siempre que sea posible…. todo dentro de '' necesita ser explicado….o tengo que ir a través de todo el doc
  2. 9

    Otros ya han mencionado el escape de los paréntesis, pero, ¿por qué usted necesita una copia de referencia en todo, si la primera parte de la línea es constante?

    Usted podría simplemente hacer

    sed -e 's/dbservername.*$/dbservername yyy/g'
    
    • Buen punto! Yo había aprendido sobre el uso de regex + sed y la mente sólo decidió ‘regexp’ en ver a esta tarea en particular, entonces como ‘jwz’ dijo que ‘tenía dos problemas’ (aunque no directamente, debido a la regex) 🙂
    • Este tiene mi voto porque es la solución más sencilla para un problema sencillo. El uso de una referencia inversa iba a salvar de cometer errores al escribir las dos copias de dbservername. Es obvio que aquí, pero cuando voy a modificar postgresql.conf en el sed se me hace difícil ver a simple vista si he escrito listen_address o listen_addresses (postgresql.conf). Ambos parecen plausibles, pero solo una es correcta.
  3. 2

    Estás escapando de su ( y ). Estoy bastante seguro de que usted no necesita hacer eso. Probar:

    sed-rne 's/(dbservername)[[:blank:]]+\([[:alpha:]]+\)/ yyy/gip' 
    
  4. 1

    No te puede escapar de las cosas cuando utilice comillas simples. es decir.

    echo "DBSERVERNAME    xxx" | sed -rne 's/(dbservername[[:blank:]]+)([[:alpha:]]+)/ yyy/gip'
    
  5. 1

    Usted no debe escapar de su paréntesis. Probar:

    echo "DBSERVERNAME    xxx" | sed -rne 's/(dbservername)[[:blank:]]+([[:alpha:]]+)/ yyy/gip'
    
  6. 1

    Esto podría funcionar para usted:

    echo "DBSERVERNAME     xxx" | sed 's/\S*$/yyy/'
    DBSERVERNAME     yyy
    
  7. 0

    Probar este

    sed -re 's/DBSERVERNAME[ \t]*([^\S]+)/\yyy/ig' temp.txt

    o este

    awk '{if($1=="DBSERVERNAME") $2 ="YYY"} {print $0;}' temp.txt

Dejar respuesta

Please enter your comment!
Please enter your name here