Como posso instruir o BSD sed a interpretar sequências de escape como \n e \t?

Como posso instruir o BSD sed a interpretar sequências de escape como \n e \t?

Eu tenho um comando de substituição sed que gostaria que fosse compatível com BSD sede também com GNU sed. Expressões regulares estendidas não são um problema, pois não preciso delas neste caso. Meu principal problema é a diferença na maneira como os dois sedinterpretam as sequências de escape de caracteres nosubstituiçãocordas. Minha string de substituição contém tabulações e novas linhas e eu gostaria que elas estivessem visíveis nas strings de comando para facilitar a manutenção, no entanto, o BSD sednão interpreta as sequências de escape e o GNUsed faz. Qual é a maneira apropriada de instruir seda interpretação dessas sequências de escape no BSD? Os dois trechos a seguir resumem meu problema:

GNUsed

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

rende

A
    B
C

BSDsed

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

rendimentos

AntBnC

Claramente, \ne \tnão são interpretados como sequências de escape pelo BSDsed

Agora, à minha pergunta. De acordo com a sedpágina de manual do BSD:

Para especificar um caractere de nova linha na string de substituição, coloque uma barra invertida antes dele.

Isso implica que eu precisaria preceder umliteralnova linha por uma barra invertida? Qual é a maneira apropriada de instruir seda interpretação das sequências de escape como \nno texto de substituição?

Responder1

Você pode usar aspas do bash $'...'para interpretar os escapes antes de passar a string para sed.

Na página de manual do 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.

Responder2

Se você precisar escrever scripts portáteis, você deve se limitar aos recursos doPadrão POSIX(também conhecido como Single Unix, também conhecido como Especificação Base de Grupo Aberto).Edição 7 também conhecida como POSIX-1.2008é o mais recente, mas muitos sistemas ainda não terminaram de adotá-lo.Edição 6 também conhecida como POSIX-1.2001é em geral fornecido por todos os unidades modernas.

Emsed, o significado das sequências de escape como \te \nnão é portável, exceto que em umexpressão regular, \nsignifica uma nova linha. No texto de substituição de um scomando, \nnão é portátil, mas você pode usar a sequência barra invertida-nova linha para representar uma nova linha.

Uma maneira portátil de gerar um caractere de tabulação (ou qualquer outro caractere expresso em octal) é comtr. Armazene o caractere em uma variável shell e substitua essa variável no trecho sed.

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

Observe novamente que as novas linhas precisam ser expressas de forma diferente em regexes e em stextos de substituição.

Você pode querer usarestranhoem vez de. Ele permite escapes de barra invertida, incluindo escapes octais \ooo, em cada literal de string.

Responder3

Isso foi respondido no Stack Overflow:

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

É exatamente o que jw013 disse.

Para inserir um tipo de guia literal ctrl+ VTab.

informação relacionada