如何指示 BSD sed 解释 \n 和 \t 等转义序列?

如何指示 BSD sed 解释 \n 和 \t 等转义序列?

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

GNUsed

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

产量

A
    B
C

BSDsed

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

产量

AntBnC

显然,BSD 不会将\n和解释为转义序列\tsed

现在,回答我的问题。根据 BSDsed手册页:

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

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

答案1

$'...'您可以在将字符串传递给之前使用 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.

答案2

如果您需要编写可移植脚本,您应该坚持使用POSIX标准(又名单一 Unix 又名开放组基本规范)。第 7 期,又名 POSIX-1.2008是最新的,但是很多系统还没有完成采用它。第 6 期又名 POSIX-1.2001基本上所有现代的unices都提供了。

sed\t,类似于和 的转义序列的含义\n是不可移植的,除了在正则表达式,\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/'
}

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

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

答案3

Stack Overflow 上已经回答了这个问题:

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

和 jw013 说的差不多。

为了插入文本制表符,请键入ctrl+ VTab

相关内容