Bash parameter expansion rules for backslash chara

2019-07-17 20:38发布

I have a variable, and I want to replace every occurrence of backslash ('\') with double backslash ('\\') using Shell parameter expansion. Originally, I used the following construction:

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

This works fine, but it breaks vim syntax highlighting - apparently, vim cannot handle \\} part. So, I decided to store backslash in a variable and use to to avoid syntax highlighting issues:

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

To my surprise, it does not work, although it would work fine with any alphanumeric symbol. So, maybe I need to store 2 backslashes in a variable? Let's try it:

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

Now, it went from not working to working twice the time I need. Eventually, I found that the only way to achieve desired result and preserve vim highlighting is the following:

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

While I already found a way to solve my issue, my question is: why parameter expansion works this way with a backslash? To me, such behavior makes no sense.

1条回答
男人必须洒脱
2楼-- · 2019-07-17 21:14

According to the Bash manual, with ${parameter/pattern/string}, "the pattern is expanded to produce a pattern just as in pathname expansion." Quoting the variable will protect it from pathname expansion and quote/backslash removal.

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

For what it's worth, if you're on a GNU system you could use printf %q to achieve a similar result.

$ printf '%q\n' "$var"
\\\\a\\b
查看更多
登录 后发表回答