Могу ли я сделать цикл for для переменных в оболочке bash? - PullRequest
3 голосов
/ 18 июня 2011

Я изучаю оболочку и хочу иметь возможность перебирать некоторые переменные. Кажется, я не могу найти где-нибудь, где кто-то делал это, поэтому я не уверен, что это вообще возможно.

По сути, я просто хочу избавить себя от проблем, используя одну и ту же команду sed для каждой из этих переменных. Однако код явно не работает. У меня вопрос, возможно ли зацикливание переменных, и если нет, то как мне это сделать?

title="$(echo string1)"
artist="$(echo string2)"
album="$(echo string3)"

for arg in title artist album do
    $arg="$(echo "$arg" | sed -e 's/&/\&amp;/g' -e 's/</\&lt;/g' -e 's/>/\&gt;/g')"
done

вот ошибка:

line 12: syntax error near unexpected token `$arg="$(echo "$arg" | sed -e 's/&/\&amp;/g' -e 's/</\&lt;/g' -e 's/>/\&gt;/g')"'

1 Ответ

5 голосов
/ 18 июня 2011

Ваша проблема не в цикле, а в назначении.Имя переменной должно быть буквальным в присваивании, т. Е. Вы можете написать 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//&/&amp;}
  value=${value//</&lt;}
  value=${value//>/&gt;}
  eval $arg=\$value
done
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...