Why does bash make an additional and unnecessary substitution & for the word that was replaced when replacing a substring?
Test replace string in bash:
test="test string MARKER end"; echo "${test/MARKER/new value '&' why & in new value was replaced}"
I've got output:
test string new value & why MARKER in new value was replaced end
why is there a MARKER here again?
Why does bash make an additional and unnecessary substitution & for the word that was replaced when replacing a substring?
Test replace string in bash:
test="test string MARKER end"; echo "${test/MARKER/new value '&' why & in new value was replaced}"
I've got output:
test string new value & why MARKER in new value was replaced end
why is there a MARKER here again?
Share Improve this question edited Feb 19 at 2:39 Guillaume Outters 1,47012 silver badges20 bronze badges asked Feb 16 at 20:29 dobordxdobordx 191 silver badge3 bronze badges New contributor dobordx is a new contributor to this site. Take care in asking for clarification, commenting, and answering. Check out our Code of Conduct. 8 | Show 3 more comments1 Answer
Reset to default 6"unnecessary" is your first feeling; but in fact it can be quite useful when you want to include the matched string in the output, without certainty about the matched string.
In your example you don't have uncertainty (you know you are looking for the fixed string "MARKER"),
but let's take another example where the match is polymorphic:
prices="12.34 € + $ 9.45"
echo ${prices//[€$]/(&)} # "Either an euro, or a dollar"
# prints: 12.34 (€) + ($) 9.45
Here I knew I wanted the replaced string to be part of the replacement (between two parenthesis), but I did't know in advance if it would be an euro or a dollar.
With the &
I make sure the replacement reproduces the matched string.
&
works here or why was it introduced to work like that? – Arkadiusz Drabczyk Commented Feb 16 at 21:02bash v.5.1.16
and the output from your code shows 2&'s
and noMARKER
; what are you expecting the output to look like? – markp-fuso Commented Feb 16 at 21:08&
with the string that matched the pattern is extremely common behavior that exists in [almost?] all pattern-matching tools. Tryecho 'foo MARKER bar' | sed 's/MARKER/<&>/'
orecho 'foo MARKER bar' | awk '{sub(/MARKER/,"<&>")}1'
for example. It'd be more surprising for bash NOT to behave the same way. – Ed Morton Commented Feb 17 at 1:04patsub_replacement
optionshopt
, which was active by default in my shellbash shopt -u patsub_replacement
– dobordx Commented Feb 17 at 11:09