![如何指示 BSD sed 解释 \n 和 \t 等转义序列?](https://linux22.com/image/23658/%E5%A6%82%E4%BD%95%E6%8C%87%E7%A4%BA%20BSD%20sed%20%E8%A7%A3%E9%87%8A%20%5Cn%20%E5%92%8C%20%5Ct%20%E7%AD%89%E8%BD%AC%E4%B9%89%E5%BA%8F%E5%88%97%EF%BC%9F.png)
sed
我有一个 sed 替换命令,我希望它与 BSD以及 GNU兼容sed
。扩展正则表达式不是问题,因为在这种情况下我不需要它们。我的主要问题是两个sed
s 解释字符转义序列的方式不同替代品字符串。我的替换字符串包含制表符和换行符,我希望它们在命令字符串中可见,以便于维护,但是,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
和解释为转义序列\t
sed
现在,回答我的问题。根据 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。