我需要在 sed 命令行中引用什么? [英] What do I need to quote in sed command lines?

查看:13
本文介绍了我需要在 sed 命令行中引用什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这个站点上有很多关于如何为 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 quote may 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 相同
  • 用双引号括起来的字符会保留字面值引号内的所有字符,美元单引号反斜杠和,启用历史扩展时,感叹号.
    • 字符 dollar单引号 在双引号内保留其特殊含义.
    • 反斜杠仅在后跟以下字符之一时保留其特殊含义:$, ', ", 或换行符.双引号可以在双引号内引用引号前加一个反斜杠.
    • 如果启用,将执行历史扩展,除非使用反斜杠对出现在双引号中的感叹号进行转义.! 前面的反斜杠!删除.
    • 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.
      

      (, ), / or + (or [, 或 ]...) 似乎有任何特殊含义,需要将它们转义才能工作.见鬼,即使直接通过 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 默认使用的正则表达式:BRE.

      If I understood you right, your problem is not about bash/sh, it is about the regex flavour sed uses by default: BRE.

      其他 [= 任何 but 点、星号、插入符号和美元] 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 your s#(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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆