¿Cuál es la sintaxis correcta para encontrar una subcadena (una cadena de la cual es precedida y seguida por cadenas específicas) que no no que coincida con un patrón específico?

Por ejemplo, yo quiero tomar todas las subcadenas que inicio con BEGIN_, final con _END y la subcadena entre no igual a FOO; y reemplazar la totalidad de la cadena con el formato «(interior de la subcadena)». El siguiente partido:

  • BEGIN_bar_END -> (bar)
  • BEGIN_buz_END -> (buz)
  • BEGIN_ihfd8f398IHFf9f39_END -> (ihfd8f398IHFf9f39)

Pero BEGIN_FOO_END no coinciden.

He jugado con el siguiente, pero no parecen encontrar la sintaxis correcta:

sed -e 's/BEGIN_(^FOO)_END/($1)/g'
sed -e 's/BEGIN_([^FOO])_END/($1)/g'
sed -e 's/BEGIN_(?!FOO)_END/($1)/g'
sed -e 's/BEGIN_(!FOO)_END/($1)/g'
sed -e 's/BEGIN_(FOO)!_END/($1)/g'
sed -e 's/BEGIN_!(FOO)_END/($1)/g'
InformationsquelleAutor Anthony | 2012-01-29

4 Comentarios

  1. 36

    No existe ningún operador de negación en sed, si mal no recuerdo porque compilación de expresiones regulares con la negación a DFAs toma de tiempo exponencial. Usted puede evitar esto con

    '/BEGIN_FOO_END/b; s/BEGIN_\(.*\)_END/()/g'

    donde /BEGIN_FOO_END/b significa: si nos encontramos con BEGIN_FOO_END, entonces rama (salto) hasta el final de la sed script.

    • también se podría haber escrito sed '/BEGIN_FOO_END/!s/BEGIN_\(.*\)_END/(\1)/g'
    • Me gustaría señalar que sed '/BEGIN_FOO_END/!s|BEGIN_\(.*\)_END|(\1)|g' funciona, pero sed '|BEGIN_FOO_END|!s|BEGIN_\(.*\)_END|(\1)|g' no! Evidentemente, se permite la sustitución de un separador diferente de «/» en la última sección, pero no en la primera sección. Raro.
    • El s/// comando puede utilizar una arbitraria delimitador; direcciones no.
    • Dirección delimitadores puede ser arbitraria, sino que el primer delimitador debe ser escapado, por ejemplo: printf '%s\n' a b c | sed '\|a|,\|b|d‘ – probado con GNU sed con el --posix opción.
    • Felicitaciones por la DFA enlace!
  2. 16

    Este tema puede ser viejo, pero en aras de la exhaustividad, lo que acerca el operador de negación ! :

    Hacer todos los infelices se vuelven MUY FELIZ :

    echo -e 'happy\nhappy\nunhappy\nhappy' | sed '/^happy/! s/.*/VERY HAPPY/'

    Encontrado esta aquí : Cómo globalmente reemplazar cadenas en las líneas que NO comience con un cierto patrón

    • Yo siempre voy a la grymoire después de que vea algo relacionado con la sed. He comprobado la suya y allí estaba, justo debajo de mi nariz
  3. 4

    Esto podría funcionar para usted:

    sed 'h;s/BEGIN_\(.*\)_END/()/;/^(FOO)$/g' file

    Esto sólo funciona si sólo hay una cadena de texto por línea.

    Para varias cadenas de caracteres por línea:

    sed 's/BEGIN_\([^F][^_]*\|F[^O][^_]*\|FO[^O][^_]*\|FOO[^_]\+\)_END/\(\)/g' file

    O el más fácil de entender:

    sed 's/\(BEGIN_\)FOO\(_END\)/\n/g;s/BEGIN_\([^\n_]*\)_END/(\)/g;s/\n/FOO/g' file
  4. 2

    No sé de una bonita manera, pero siempre se puede hacer esto:

    $ cat file
    BEGIN_FOO_END
    BEGIN_FrOO_END
    BEGIN_rFOO_END
    $ sed '/BEGIN_FOO_END/!{s/BEGIN_\([^_]*\)_END/()/}' file 
    BEGIN_FOO_END
    (FrOO)
    (rFOO)

Dejar respuesta

Please enter your comment!
Please enter your name here