Addressing issues with OP's current code:
- referencing variables requires a leading
$
, preferably a pair of {}
, and (usually) double quotes (eg, to insure embedded spaces are considered as part of the variable's value)
sed
can take as input a) a stream of text on stdin, b) a file, c) process substitution or d) a here-document/here-string
- when building a
sed
script that includes variable refences the sed
script must be wrapped in double quotes (not single quotes)
Pulling all of this into OP's current code we get:
string1="One,two"
string2="three.four"
string3="five:six"
y=";"
for str in "${string1}" "${string2}" "${string3}"; do # proper references of the 3x "stringX" variables
x="$(echo "$str" | sed 's/[a-zA-Z]//g')"
sed "s/$x/$y/" <<< "${str}" # feeding "str" as here-string to sed; allowing variables "x/y" to be expanded in the sed script
echo "$str"
done
This generates:
One;two # generated by the 2nd sed call
One,two # generated by the echo
;hree.four # generated by the 2nd sed call
three.four # generated by the echo
five;six # generated by the 2nd sed call
five:six # generated by the echo
OK, so we're now getting some output but there are obviously some issues:
- the results of the 2nd
sed
call are being sent to stdout/terminal as opposed to being captured in a variable (presumably the str
variable - per the follow-on echo
???)
- for
string2
we find that x=.
which when plugged into the 2nd sed
call becomes sed "s/./;/"
; from here the .
matches the first character it finds which in this case is the 1st t
in string2
, so the output becomes ;hree.four
(and the .
is not replaced)
- dynamically building
sed
scripts without knowing what's in x
(and y
) becomes tricky without some additional coding; instead it's typically easier to use parameter substitution to perform the replacements for us
- in this particular case we can replace both
sed
calls with a single parameter substitution (which also eliminates the expensive overhead of two subprocesses for the $(echo ... | sed ...)
call)
Making a few changes to OP's current code we can try:
string1="One,two"
string2="three.four"
string3="five:six"
y=";"
for str in "${string1}" "${string2}" "${string3}"; do
x="${str//[^a-zA-Z]/${y}}" # parameter substitution; replace everything *but* a letter with the contents of variable "y"
echo "${str} => ${x}" # display old and new strings
done
This generates:
One,two => One;two
three.four => three;four
five:six => five;six