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 <v...@larryv.me> 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
>

Reply via email to