Ваша проблема не в цикле, а в назначении.Имя переменной должно быть буквальным в присваивании, т. Е. Вы можете написать title=some_value
, но не $arg=some_value
.
. Переносимый способ присвоения переменной с переменным именем - использовать eval
.Вам также необходимо получить значение $arg
(а не только значение arg
, что составляет $arg
), что снова требует использования eval
.
new_value="$(eval printf %s \"\$$arg\" | …)"
eval $arg=\$new_value
Другой способ присвоенияпеременная с переменным именем, которая специфична для bash / ksh / zsh, но не будет работать в простом порядке, это использовать встроенный typeset
.В bash, если вы делаете это в функции, это делает назначение локальным для функции.Чтобы получить значение переменной с переменным именем, вы можете использовать ${!arg}
;это относится только к bash.
typeset $arg="$(printf %s "${!arg}" | …)"
Другие проблемы с вашим фрагментом:
title="$(echo string1)"
- это сложный способ написания title="string1"
, который, кроме того, может исказить string1
если он содержит обратную косую черту или начинается с -
. - Вам нужен терминатор команды (
;
или новая строка) перед ключевым словом do
.
Если вы полагаетесьв bash / ksh / zsh вы можете сделать замены внутри оболочки с помощью конструкции ${VARIABLE//PATTERN/REPLACEMENT}
.
title="string1"
artist="string2"
album="string3"
for arg in title artist album; do
eval value=\$$arg
value=${value//&/&}
value=${value//</<}
value=${value//>/>}
eval $arg=\$value
done