如何在单引号字符串中转义单引号?

比方说,你有一个bash alias

alias rxvt='urxvt'

这工作正常。

然而:

alias rxvt='urxvt -fg '#111111' -bg '#111111''

将不起作用,也不会:

alias rxvt='urxvt -fg '#111111' -bg '#111111''

那么,一旦你已经逃脱了引号,你怎么最终匹配一个字符串中的开头和结尾的引号?

alias rxvt='urxvt -fg'''#111111''' -bg '''#111111'''

看起来很笨拙,但如果允许像这样连接它们,它会代表相同的字符串。


如果您确实想在最外层使用单引号,请记住您可以粘合两种引用。 例:

 alias rxvt='urxvt -fg '"'"'#111111'"'"' -bg '"'"'#111111'"'"
 #                     ^^^^^       ^^^^^     ^^^^^       ^^^^
 #                     12345       12345     12345       1234

'"'"'被解释为' '"'"'的解释:

  • '结束使用单引号的第一个引号。
  • "用双引号开始第二个引号。
  • '引用的字符。
  • "结束第二次引用,使用双引号。
  • '使用单引号开始第三个引号。
  • 如果在(1)和(2)之间或者(4)和(5)之间没有放置任何空格,则shell会将该字符串解释为单个长字。


    我总是用序列'''替换每个嵌入的单引号(即:引号反斜杠引号引用),它会关闭字符串,附加一个转义的单引号并重新打开字符串。


    我经常在我的Perl脚本中调用“quotify”函数来为我做这件事。 步骤是:

    s/'/'''/g    # Handle each embedded quote
    $_ = qq['$_']; # Surround result with single quotes.
    

    这几乎照顾了所有情况。

    当您将eval引入shell脚本时,生活会变得更加有趣。 你基本上不得不重新引用所有的东西!

    例如,创建一个名为quotify的Perl脚本,其中包含上述语句:

    #!/usr/bin/perl -pl
    s/'/'''/g;
    $_ = qq['$_'];
    

    然后用它来生成一个正确引用的字符串:

    $ quotify
    urxvt -fg '#111111' -bg '#111111'
    

    结果:

    'urxvt -fg '''#111111''' -bg '''#111111''''
    

    然后可以将其复制/粘贴到别名命令中:

    alias rxvt='urxvt -fg '''#111111''' -bg '''#111111''''
    

    (如果您需要将该命令插入到eval中,请再次运行quotify:

     $ quotify
     alias rxvt='urxvt -fg '''#111111''' -bg '''#111111''''
    

    结果:

    'alias rxvt='''urxvt -fg '''''''''#111111''''''''' -bg '''''''''#111111'''''''''''''
    

    可以将其复制/粘贴到评估中:

    eval 'alias rxvt='''urxvt -fg '''''''''#111111''''''''' -bg '''''''''#111111'''''''''''''
    

    由于Bash 2.04语法$'string' (而不是'string' )是另一种引用机制,它允许ANSI C类似的转义序列并扩展为单引号版本。

    简单的例子:

      $> echo $'aa'bb'
      aa'bb
    
      $> alias myvar=$'aa'bb'
      $> alias myvar
      alias myvar='aa'''bb'
    

    在你的情况下:

    $> alias rxvt=$'urxvt -fg '#111111' -bg '#111111''
    $> alias rxvt
    alias rxvt='urxvt -fg '''#111111''' -bg '''#111111''''
    

    常见的转义序列按预期工作:

    '     single quote
    "     double quote
         backslash
    n     new line
    t     horizontal tab
    r     carriage return
    

    下面是从man bash (版本4.4)复制粘贴的相关文档:

    特殊处理$'string'形式的单词。 该字扩展为字符串,反斜杠转义字符被替换为ANSI C标准指定的字符。 反斜杠转义序列(如果存在)按如下方式解码:

        a     alert (bell)
        b     backspace
        e
        E     an escape character
        f     form feed
        n     new line
        r     carriage return
        t     horizontal tab
        v     vertical tab
             backslash
        '     single quote
        "     double quote
        ?     question mark
        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 hexadecimal
               value HH (one or two hex digits)
        uHHHH the Unicode (ISO/IEC 10646) character whose value is 
               the hexadecimal value HHHH (one to four hex digits)
        UHHHHHHHH the Unicode (ISO/IEC 10646) character whose value 
                   is the hexadecimal value HHHHHHHH (one to eight 
                   hex digits)
        cx    a control-x character
    

    扩大的结果是单引号的,就好像美元符号不存在一样。


    有关更多详细信息,请参阅引用和转义:ANSI C像bash-hackers.org wiki上的字符串。 另外请注意,“Bash Changes”文件(此处概述)提到了与$'string'引用机制相关的更改和错误修复。

    根据unix.stackexchange.com如何使用一个特殊的字符作为一个正常的? 它应该在bash,zsh,mksh,ksh93和FreeBSD以及busybox sh中工作(有一些变化)。

    链接地址: http://www.djcxy.com/p/1677.html

    上一篇: How to escape single quotes within single quoted strings?

    下一篇: Extract filename and extension in Bash