BASH с использованием двойной переменной $ - неправильная замена

Из моего кода ниже, как сделать значение «zz» равным 500 после замены «critical_» на x в переменной «yy»

xab123=500

yy="critical_ab123"
zz=${"${yy//critical_/x}"}

echo $zz

вместо результата возникает ошибка:

line 8: ${"${yy//critical_/x}"}: bad substitution

спасибо ади


person adiwhy    schedule 16.01.2014    source источник


Ответы (2)


Может быть так:

xab123=500
yy="critical_ab123"
zz="${yy//critical_/x}"
echo ${!zz}
500
person anubhava    schedule 16.01.2014
comment
спасибо, это работает - person adiwhy; 16.01.2014
comment
Пожалуйста, рад, что все получилось. - person anubhava; 16.01.2014

Интересное использование: когда вы вызываете функцию bash, вы можете использовать косвенность для переданных параметров. Затем вы можете вкладывать вызовы вашей функции косвенности вложенным образом, используя подстановку команд.

deref() { echo "${!1}"; }

aa="bb"
bb="cc"
cc="hello"

echo "$(deref aa)" # bb
echo "$(deref "$(deref aa)")" # cc
echo "$(deref "$(deref "$(deref aa)")")" # hello

Здесь deref используется для решения проблемы OP:

deref() { echo "${!1}"; }

xab123="500"
yy="critical_ab123"
zz="$(deref "${yy//critical_/x}")"

echo "$zz" # Outputs: 500

Внесены правки на основе комментариев @charles-duffy:

  1. Отказ от ответственности: будьте осторожны, читатель, подстановка команд, используемая в этом подходе, влияет на производительность (создание FIFO, fork() подоболочки, read() и wait()).
  2. Добавлены кавычки для защиты от расширения с потерями, т.е. echo "$zz" лучше, чем echo $zz
  3. Используйте синтаксис объявления функций, совместимый с POSIX, т. е. замените function deref { echo "${!1}" ; } на deref() { echo "${!1}" ; }.
  4. Исправлена ​​проблема с цитированием для каждого контекста цитирования.
person Stephen Quan    schedule 24.04.2017
comment
Бу, шипение: подстановка команд не нужна и оказывает значительное влияние на производительность (требуется создание FIFO, fork() подоболочки, read() и wait() для того же), отсутствие кавычек делает эту операцию с потерями (echo $zz заменит * списком файлов в текущий каталог), а нестандартный синтаксис объявления функций не имеет абсолютно никаких преимуществ по сравнению с альтернативой, совместимой с POSIX. - person Charles Duffy; 20.11.2017
comment
@charles-duffy Я понял ваш отзыв. Я подумал об удалении этого ответа, но вместо этого решил попытаться улучшить его. Я считаю, что правильно понял ваши мысли, за исключением того, что я не понял нестандартного объявления функции. Можете ли вы предоставить ссылку? - person Stephen Quan; 21.11.2017
comment
См. соответствующий документ со стандартами по адресу pubs.opengroup.org/onlinepubs/9699919799/ утилиты/ -- определение, совместимое со стандартами, будет deref() { echo "${!1}"; } без предшествующего ключевого слова function. - person Charles Duffy; 21.11.2017
comment
Кстати, правильное цитирование (чтобы гарантировать, что мы передаем наш результат изменения yy в качестве одного аргумента, независимо от наличия пробелов или значения IFS) будет zz="$(deref "${yy//critical_/x}")" - каждая замена команды с $() запускает новый контекст цитирования. Таким образом, вызов с yy='hello world' правильно вызовет ошибку, вместо того, чтобы дереффить переменную с именем hello и молча игнорировать world. - person Charles Duffy; 21.11.2017
comment
(аналогично: "$(deref "$(deref "$(deref aa)")")") - person Charles Duffy; 21.11.2017