【问题标题】:Bash parameter expansion rules for backslash character反斜杠字符的 Bash 参数扩展规则
【发布时间】:2016-06-30 23:29:21
【问题描述】:

我有一个变量,我想使用Shell parameter expansion 将每次出现的反斜杠 ('\') 替换为双反斜杠 ('\\')。最初,我使用了以下构造:

$ var='\\a\b'
$ echo "${var//\\/\\\\}"
\\\\a\\b

这很好用,但它破坏了 vim 语法突出显示 - 显然,vim 无法处理 \\} 部分。因此,我决定将反斜杠存储在一个变量中并用来避免语法高亮问题:

$ bsl='\'
$ echo "${var//$bsl/$bsl$bsl}"
\\a\b

令我惊讶的是,它不起作用,尽管它适用于任何字母数字符号。那么,也许我需要在一个变量中存储 2 个反斜杠?让我们试试吧:

$ bsl='\\'
$ echo "${var//$bsl/$bsl$bsl}"
\\\\\\\\a\\\\b

现在,它从不工作变成了我需要的两倍工作时间。最终,我发现达到预期结果并保持 vim 突出显示的唯一方法如下:

$ bsl='\'
$ echo "${var//\\/$bsl$bsl}"
\\\\a\\b

虽然我已经找到了解决问题的方法,但我的问题是:为什么参数扩展使用反斜杠以这种方式工作?对我来说,这样的行为毫无意义。

【问题讨论】:

    标签: string bash shell replace


    【解决方案1】:

    根据 Bash 手册,${parameter/pattern/string},“模式被扩展以产生一个模式,就像在路径名扩展中一样。”引用变量将保护它免受路径名扩展和引号/反斜杠删除。

    $ echo "${var//$bsl/$bsl$bsl}"
    \\a\b
    $ echo "${var//"$bsl"/$bsl$bsl}"
    \\\\a\\b
    

    不管怎样,如果您使用的是 GNU 系统,则可以使用 printf %q 来获得类似的结果。

    $ printf '%q\n' "$var"
    \\\\a\\b
    

    【讨论】:

    • 但是,如果我引用替换部分,同时删除整个变量周围的引号,它也可以正常工作:$ echo ${var//"$bsl"/"$bsl$bsl"} -> \\\\a\\b。我还是不明白。
    • 引号/反斜杠删除仅适用于不是扩展结果的字符。不需要引用来保护$var 中的反斜杠不被删除。不过, 有助于防止结果受到通配符和分词的影响。
    • 为清楚起见,bash 扩展 $bsl 并在此处引用生成的字符串,模式匹配机制稍后会执行模式上的反斜杠删除。下面清楚地演示了应用于模式和替换零件的不同扩展规则:var='\\a\b' bsl='\\'; echo "${var//$bsl/$bsl}"。这让我困扰了将近一年,该死的。
    猜你喜欢
    • 2017-03-08
    • 2013-03-12
    • 2014-10-22
    • 2013-08-11
    • 2014-09-11
    • 1970-01-01
    • 2011-05-18
    • 2016-08-07
    • 1970-01-01
    相关资源
    最近更新 更多