¿Cómo puedo indicarle a BSD sed que interprete secuencias de escape como \n y \t?

¿Cómo puedo indicarle a BSD sed que interprete secuencias de escape como \n y \t?

Tengo un comando de reemplazo sed que me gustaría que fuera compatible tanto con BSD sedcomo con GNU sed. Las expresiones regulares extendidas no son un problema ya que no las necesito en este caso. Mi principal problema es la diferencia en la forma en que los dos sedinterpretan las secuencias de escape de caracteres en elreemplazoinstrumentos de cuerda. Mi cadena de reemplazo contiene tabulaciones y nuevas líneas y me gustaría que fueran visibles en las cadenas de comando para facilitar el mantenimiento; sin embargo, BSD sedno interpreta las secuencias de escape y GNUsed hace. ¿Cuál es la forma apropiada de dar instrucciones sedpara interpretar estas secuencias de escape en BSD? Los siguientes dos fragmentos resumen mi problema:

ÑUsed

echo ABC | sed 's/B/\n\tB\n'

rinde

A
    B
C

BSDsed

echo ABC | sed 's/B\n\tB\n'

rendimientos

AntBnC

Claramente, \ny \tBSD no las interpreta como secuencias de escape.sed

Ahora, a mi pregunta. Según la sedpágina de manual de BSD:

Para especificar un carácter de nueva línea en la cadena de reemplazo, precedido por una barra invertida.

¿Esto implica que necesitaría preceder a unliteral¿nueva línea por una barra invertida? ¿Cuál es la forma adecuada de dar instrucciones sedpara interpretar secuencias de escape como \nen el texto de reemplazo?

Respuesta1

Puede utilizar las $'...'comillas bash para interpretar los escapes antes de pasar la cadena a sed.

Desde la página de manual de bash:

   Words  of  the  form  $'string'  are  treated specially.  The word
   expands to string, with backslash-escaped characters  replaced  as
   specified  by the ANSI C standard.  Backslash escape sequences, if
   present, are decoded as follows:
          \a     alert (bell)
          \b     backspace
          \e     an escape character
          \f     form feed
          \n     new line
          \r     carriage return
          \t     horizontal tab
          \v     vertical tab
          \\     backslash
          \'     single quote
          \nnn   the eight-bit character whose  value  is  the  octal
                 value nnn (one to three digits)
          \xHH   the eight-bit character whose value is the hexadeci-
                 mal value HH (one or two hex digits)
          \cx    a control-x character

   The expanded result is single-quoted, as if the  dollar  sign  had
   not been present.

   A  double-quoted  string  preceded by a dollar sign ($) will cause
   the string to be translated according to the current  locale.   If
   the  current locale is C or POSIX, the dollar sign is ignored.  If
   the string is translated and replaced, the replacement is  double-
   quoted.

Respuesta2

Si necesita escribir scripts portátiles, debe ceñirse a las funciones delestándar POSIX(también conocido como Single Unix, también conocido como Especificación básica de grupo abierto).Número 7 también conocido como POSIX-1.2008es el último, pero muchos sistemas aún no han terminado de adoptarlo.Número 6 también conocido como POSIX-1.2001es proporcionado en general por todos los unices modernos.

Ensed, el significado de secuencias de escape como \ty \nno es portátil, excepto que en unexpresión regular, \nrepresenta una nueva línea. En el texto de reemplazo de un scomando, \nno es portátil, pero puede usar la secuencia barra invertida-nueva línea para representar una nueva línea.

Una forma portátil de generar un carácter de tabulación (o cualquier otro carácter expresado en octal) es contr. Almacene el carácter en una variable de shell y sustituya esta variable en el fragmento sed.

tab=$(echo | tr '\n' '\t')
escape=$(echo | tr '\n' '\033')
embolden () {
  sed -e 's/^/'"$escape"'[1m/' -e 's/$/'"$escape"'[0m/'
}

Tenga en cuenta nuevamente que las nuevas líneas deben expresarse de manera diferente en las expresiones regulares y en slos textos de reemplazo.

Es posible que desee utilizarawken cambio. Permite escapes de barra invertida, incluidos escapes octales \ooo, en cada cadena literal.

Respuesta3

Esto ha sido respondido en Stack Overflow:

https://stackoverflow.com/questions/1421478/how-do-i-use-a-new-line-replacement-in-a-bsd-sed

Es más o menos exactamente lo que dijo jw013.

Para insertar una pestaña literal, escriba ctrl+ VTab.

información relacionada