我如何指示 BSD sed 解释像 \n 和 \t 这样的转义序列?

eph*_*ith 14 bsd sed

我有一个 sed 替换命令,我希望它与 BSDsed和 GNU兼容sed。扩展正则表达式不是问题,因为在这种情况下我不需要它们。我的主要问题是两个seds 解释替换字符串中的字符转义序列的方式不同。我的替换字符串包含制表符和换行符,为了便于维护,我希望它们在命令字符串中可见,但是,BSDsed不解释转义序列,而 GNUsed 可以。指示sed在 BSD 上解释这些转义序列的适当方法是什么?以下两个片段概括了我的问题:

GNU sed

echo ABC | sed 's/B/\n\tB\n'
Run Code Online (Sandbox Code Playgroud)

收益率

A
    B
C
Run Code Online (Sandbox Code Playgroud)

BSD sed

echo ABC | sed 's/B\n\tB\n'
Run Code Online (Sandbox Code Playgroud)

产量

AntBnC
Run Code Online (Sandbox Code Playgroud)

显然,\n并且\t不会被 BSD 解释为转义序列sed

现在,我的问题。根据 BSDsed联机帮助页:

要在替换字符串中指定换行符,请在其前面加上反斜杠。

这是否意味着我需要在文字换行符之前加上反斜杠?指示sed解释\n替换文本中的转义序列的适当方法是什么?

Kev*_*vin 7

您可以使用bash中$'...'引用的字符串传递给前解释逃逸sed

从 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.
Run Code Online (Sandbox Code Playgroud)


Gil*_*il' 6

如果您需要编写可移植的脚本,您应该坚持使用POSIX 标准(又名 Single Unix 又名 Open Group Base Specification)中的特性。Issue 7 aka POSIX-1.2008是最新的,但许多系统还没有完全采用它。Issue 6 aka POSIX-1.2001 基本上由所有现代 unice 提供。

sed 中,转义序列的含义 like\t\n不可移植,除了在regex 中\n代表换行符。在s命令的替换文本中,\n不可移植,但您可以使用序列反斜杠-换行符来代表换行符。

生成制表符(或任何其他以八进制表示的字符)的可移植方式是使用tr. 将字符存储在 shell 变量中,并在 sed 片段中替换此变量。

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

再次注意,换行需要在正则表达式和s替换文本中以不同的方式表达。

您可能想改用awk。它允许\ooo在每个字符串文字中进行反斜杠转义,包括八进制转义。