如何在单引号引起来的字符串中转义单引号

穿精又带淫゛_ 提交于 2019-12-15 12:52:54

【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>>

假设您有一个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'\''

看起来很笨拙,尽管如果允许您将它们串联起来,它将表示相同的字符串。


#1楼

我没有在他的博客上看到该条目(请链接?),但是根据gnu参考手册

将字符括在单引号(''')中可保留引号内每个字符的字面值。 即使在单引号之前加反斜杠,也不能在单引号之间引起单引号。

所以bash无法理解:

alias x='y \\'z '

但是,如果用双引号引起来,则可以执行以下操作:

alias x="echo \'y "
> x
> 'y

#2楼

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

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

'"'"'如何解释为仅'

  1. '结束使用单引号的引号。
  2. "使用双引号开始第二个引号。
  3. '引用字符。
  4. "使用双引号结束第二个引号。
  5. '使用单引号将第三个引号引起来。

如果您没有在(1)和(2)之间或(4)和(5)之间放置任何空格,则Shell会将该字符串解释为一个长字。


#3楼

我并不是专门解决报价问题,因为有时候考虑替代方法是合理的。

rxvt() { urxvt -fg "#${1:-000000}" -bg "#${2:-FFFFFF}"; }

您可以将其称为:

rxvt 123456 654321

的想法是,您现在可以对此进行别名而不用担心引号:

alias rxvt='rxvt 123456 654321'

或者,如果由于某种原因需要在所有调用中包含#

rxvt() { urxvt -fg "${1:-#000000}" -bg "${2:-#FFFFFF}"; }

您可以将其称为:

rxvt '#123456' '#654321'

那么,别名当然是:

alias rxvt="rxvt '#123456' '#654321'"

(糟糕,我想我确实解决了这个问题:)


#4楼

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


我经常在我的Perl脚本中鞭打一个“报价”功能来为我做这件事。 步骤将是:

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命令中:

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

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

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

结果:

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

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

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

#5楼

由于Bash 2.04语法$'string' (而不是'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

扩展结果是单引号,好像没有美元符号。


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

根据unix.stackexchange.com, 如何使用特殊字符作为普通字符? 它应该在bash,zsh,mksh,ksh93和FreeBSD和busybox sh中工作(有一些变体)。

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!