I think that helps me understand the differences better, and what I am
seeing.
Though It doesn't seem like it is completely consistent, and not what I
expected when using a variable with specific layout. (and also breaking
change enabled by default)
example, if i change the replacement to '\a'
it stays as \a
$ bash replacestring.sh
original: 1|2|3|4 replace:\a
unqouted 1|\a|3|4
qouted 1|\a|3|4
so, it seems it only escapes it if its a double backslash, or escaping a &
and it is different again, if i change the script to do \a manually
$ cat replacestring.sh
original_string="1|2|3|4"
replace_string='\a'
echo "original: ${original_string} replace:${replace_string}"
echo "unqouted ${original_string/2/${replace_string}}"
echo "qouted ${original_string/2/"${replace_string}"}"
echo "manual ${original_string/2/\a}"
output for newer bash:
...
manual 1|a|3|4
this is slightly different behaviour from the variable, but in older
versions, it shows it
GNU bash, version 4.2.46(2)-release (x86_64-redhat-linux-gnu)
$ bash /tmp/replacestring.sh
original: 1|2|3|4 replace:\a
unqouted 1|\a|3|4
qouted 1|"\a"|3|4
manual 1|\a|3|4
It could also be a double quote, '\"' that is escaped, and it doesn't
interpret the \ as an escape, which is a character that I would expect to
see that happen for.
also, a single \ doesn't have to be quoted either
replace_string='\'
Anyway, this does help, as I can look into turning it off, and understand
the behaviour better.
Jeff
On Thu, Jun 19, 2025 at 4:11 PM Lawrence Velázquez <[email protected]> wrote:
> On Thu, Jun 19, 2025, at 5:28 PM, Jeff Ketchum wrote:
> > $ cat replacestring.sh
> > original_string="1|2|3|4"
> > replace_string=':\\'
> > echo "original: ${original_string} replace:${replace_string}"
> > echo "unquoted ${original_string/2/${replace_string}}"
> > echo "quoted ${original_string/2/"${replace_string}"}"
> >
> > [...]
> >
> > on older versions, this was a little different:
> > GNU bash, version 4.1.2(2)-release (x86_64-redhat-linux-gnu)
> > $ bash /tmp/replacestring.sh
> > original: 1|2|3|4 replace::\\
> > unquoted 1|:\\|3|4
> > quoted 1|":\\"|3|4
> >
> >
> > Then, there was an inbetween version: (custom but based on this)
> > GNU bash, version 5.1.16(1)-release (x86_64-pc-linux-musl)
> > original: 1|2|3|4 replace::\\
> > unquoted 1|:\\|3|4
> > quoted 1|:\\|3|4
>
> This changed in bash 4.3:
>
> There is one incompatible change between bash-4.2 and
> bash-4.3. Bash now performs quote removal on the replacement
> string in pattern substitution (${param/pat/rep}), since
> the shell treats quotes as special. If you have to quote
> single quotes to get them to be treated literally, the shell
> should perform quote removal on them.
>
> https://lists.gnu.org/archive/html/bug-bash/2014-02/msg00081.html
>
> > [...]
> >
> > GNU bash, version 5.2.37(1)-release (x86_64-pc-linux-gnu)
> > $ bash replacestring.sh
> > original: 1|2|3|4 replace::\\
> > unquoted 1|:\|3|4
> > quoted 1|:\\|3|4
>
> This changed in bash 5.2:
>
> There is a new shell option, `patsub_replacement'. When
> enabled, a `&' in the replacement string of the pattern
> substitution expansion is replaced by the portion of the
> string that matched the pattern. Backslash will escape the
> `&' and insert a literal `&'. This option is enabled by
> default.
>
> (Since '\' is now an escape character, the fact that it escapes
> itself is implied.)
>
> https://lists.gnu.org/archive/html/bug-bash/2022-09/msg00056.html
>
> --
> vq
>