我需要在sed命令行中引用什么? [英] What do I need to quote in sed command lines?
问题描述
此网站上有许多有关如何逃避sed的各种问题的问题,但我正在寻找更一般的答案.我知道我可能想转义一些字符以避免shell扩展:
There are many questions on this site on how to escape various elements for sed, but I'm looking for a more general answer. I understand that I might want to escape some characters to avoid shell expansion:
Bash :
- 单引号[strings] ('')用于保留引号内每个字符的字面值.[但是,]即使在单引号前加上反斜杠,也可能不会出现
单引号. - 仅当后跟美元,反引号,双引号时,反斜杠才保留其含义[在双引号字符串中]strong>,反斜杠或换行符.在双引号中,当反斜杠后面是这些字符之一时,将从输入流中删除.没有特殊含义的反斜杠前面的字符将保留不变,以供shell解释器处理.
- Single quoted [strings] ('') are used to preserve the literal value of each character enclosed within the quotes. [However,] a
single quotemay not occur between single quotes, even when preceded by a backslash. - The backslash retains its meaning [in double quoted strings] only when followed by dollar, backtick, double quote, backslash or newline. Within double quotes, the backslashes are removed from the input stream when followed by one of these characters. Backslashes preceding characters that don't have a special meaning are left unmodified for processing by the shell interpreter.
sh :(我希望您没有历史扩展)
sh: (I hope you don't have history expansion)
- 单引号字符串行为:与bash相同
- 用双引号引起来的字符保留了字面值引号中的所有字符,但美元,单引号,反斜杠和启用历史记录扩展后,请感叹号.
-
美元
和单引号这些字符在双引号中保留其特殊含义. - 仅当反斜杠后面跟随以下字符之一时,才保留其特殊含义:
$
,'
,"
,\
或换行符.双引号可能用双引号引起来用反斜杠加引号. - 如果启用,将执行历史记录扩展,除非使用反斜杠将出现在双引号中的感叹号转义.!前面的反斜杠已被未删除.
- Single quoted string behaviour: same as bash
- Enclosing characters in double quotes preserves the literal value of
all characters within the quotes, with the exception of dollar, single quote, backslash, and,
when history expansion is enabled, exclamation mark.
- The characters
dollar
and single quote retain their special meaning within double quotes. - The backslash retains its special meaning only when followed by one of the following characters:
$
,'
,"
,\
, or newline. A double quote may be quoted within double quotes by preceding it with a backslash. - If enabled, history expansion will be performed unless an exclamation mark appearing in double quotes is escaped using a backslash. The backslash preceding the ! is not removed.
...但是这些都无法解释为什么您删除任何转义符后,该操作就停止工作:
...but none of that explains why this stops working as soon as you remove any escaping:
sed -e "s#\(\w\+\) #\1\/#g" #find a sequence of characters in a line # why? ↑ ↑ ↑ ↑ #replace the following space with a slash.
(
,)
,/
或+
(或[
,或]
...)似乎有任何特殊含义,需要对其进行转义才能正常工作.地狱,即使直接通过Python调用命令也会使sed无法正常工作,尽管联机帮助页似乎并未对此进行任何说明(无论如何,我搜索反斜杠时都没有.)None of
(
,)
,/
or+
(or[
, or]
...) seem to have any special meaning that requires them to be escaped in order to work. Hell, even calling the command directly through Python makes sed not work properly, although the manpage doesn't seem to spell out anything about this (not when I search for backslash, anyway.)$ lvdisplay -C --noheadings -o vg_name,name > test $ python >>> import os >>> #Python requires backslash escaping of \1, even in triple quotes >>> #lest \1 is read to mean "byte with value 0x01". >>> output = os.execl("/bin/sed", "-e", "s#(\w+) #\\1/#g", "test") (Output remains unchanged) $ python >>> import os >>> output = os.execl("/bin/sed", "-e", "s#\(\w\+\) #\\1\/#g", "test") (Correct output) $ WHAT THE HELL Have you tried using jQuery? It's perfect and it does all the things.
推荐答案
如果我没看错,您的问题与bash/sh无关,而是默认情况下sed使用的regex风味:
If I understood you right, your problem is not about bash/sh, it is about the regex flavour sed uses by default: BRE.
其他[=除以外的其他任何 点,星,插入号和美元)BRE元字符需要使用反斜杠以赋予其特殊含义.原因是UNIX
grep
的最旧版本不支持这些版本.The other [= anything but dot, star, caret and dollar] BRE metacharacters require a backslash to give them their special meaning. The reason is that the oldest versions of UNIX
grep
did not support these.分组
(..)
应该转义以赋予它特殊的含义.与+
相同,否则sed将尝试匹配它们,因为它们是文字字符串/字符.这就是为什么您的s#\(\ w \ + \)#...#
应该转义的原因.替换部分不需要转义,所以:Grouping
(..)
should be escaped to give it special meaning. same as+
otherwise sed will try to match them as they are literal strings/chars. That's why yours#\(\w\+\) #...#
should be escaped. The replacement part doesn't need escaping, so:sed 's#\(\w\+\) #\1 /#'
应该工作.
sed
通常可以选择使用扩展的正则表达式(现在带有?
,+
,|
,()
,{m,n}
);例如GNU sed具有-r
,那么您的一线可能是:sed
has usually option to use extended regular expressions (now with?
,+
,|
,()
,{m,n}
); e.g. GNU sed has-r
, then your one-liner could be:sed -r 's#(\w+) #\1 /#'
我在此处粘贴一些示例,这些示例可以帮助您了解发生的情况:
I paste some examples here that may help you understand what's going on:
kent$ echo "abcd "|sed 's#\(\w\+\) #\1 /#' abcd / kent$ echo "abcd "|sed -r 's#(\w+) #\1 /#' abcd / kent$ echo "(abcd+) "|sed 's#(\w*+) #&/#' (abcd+) /
这篇关于我需要在sed命令行中引用什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
- The characters
-