LINUX.ORG.RU
ФорумAdmin

eval и массивы

 ,


0

4

Есть несколько массивов:

mas1=(1 2 3 4 5)
mas2=(6 7 8 9 0)
mas3=(a s d f g)

Не получается перебрать массивы меняя их коэффициент и скопировать один массив в другой.
Делаю это вот так:

mas1=(1 2 3 4 5)
mas2=(6 7 8 9 0)
mas3=(a s d f g)
declare -a MASSIV
per="mas"
for(( i=1 ; i<4 ; i++ ))
 do
   zk=$per$i
   eval MASSIV=("${zk[@]}")
done

Перебрал уже много вариантов:

eval MASSIV=("${$zk[@]}")
eval MASSIV=("${\$zk[@]}")
eval MASSIV=("${'$'zk[@]}")
eval MASSIV=( ${"$zk"[@]} )
и т. д.
но выдаёт ошибку или копируется только первый элемент массива.

★★

Пожалуйста, не надо писать на баше как на бейсике! Твоя задача решается без евала, но это плохая, негодная задача, её не надо решать. Просто представь, что твои массивы бесконечной длинны и читаются из файлов и обработай их в таком стиле, через фильтры и конвейеры и у тебя получится более простое и понятное решение, чем это и уродство с for и eval.

legolegs ★★★★★
()

Перебрал уже много вариантов:

Нет ;) Не надо перебирать, надо понимать, что должно получиться:

eval MASSIV='("${'$per$i'[@]}")'

или без eval, но на самом деле это всё равно тот же самый eval, и потому без гарантии:

zk=$per$i[@]
MASSIV=("${!zk}")

vodz ★★★★★
()
Последнее исправление: vodz (всего исправлений: 2)
Ответ на: комментарий от vodz

Спасибо за помощь! На другом форуме подсказали вот такую конструкцию:

zk=$(eval echo \${$per$i[@]})
eval MASSIV=("${zk[@]}")

В интернете нашёл таки информацию и были примеры без eval-а с восклицательным знаком, но пишут что через ssh с "!" работать не будет.
Я с этим eval до конца так и не разобрался, толком не понимаю что он делает. Вернее понятно, что он выполняет переданные ему параметры как команды, но на практике в примерах разобраться до конца не могу.

v4567 ★★
() автор топика

for(( i=1 ; i<4 ; i++ ))

это осознанно написано, или это сумрачный гений?

Anoxemian ★★★★★
()
Ответ на: комментарий от v4567

Я с этим eval до конца так и не разобрался, толком не понимаю что он делает.

Сам eval - вещь очень проста для понимания. Трудность при её использовании ровно такая же, как для олимпиадных задач: решение на первый взгляд не видно, нужно знать трюк, применив который, можно привести задачу к обычным очевидным последовательным действиям. :)

vodz ★★★★★
()
Ответ на: комментарий от vodz

for(( i=1 ; i<4 ; i++ ))
это осознанно написано, или это сумрачный гений?

Осознанно. Хотелось бы узнать, что не так?

Сам eval - вещь очень проста для понимания. Трудность при её > использовании ровно такая же, как для олимпиадных задач: решение
на первый взгляд не видно, нужно знать трюк, применив который, можно привести задачу к обычным очевидным последовательным действиям.
:)

Хотелось бы узнать этот трюк.

v4567 ★★
() автор топика
Ответ на: комментарий от v4567

Хотелось бы узнать этот трюк.

Это не возможно передать словами, иначе все бы решали олимпиадные задачи также как обычные. :)

А если серьёзно, то eval требует мыслить всего лишь на один уровень рекурсивно. Это не сложно же.

vodz ★★★★★
()
Ответ на: комментарий от vodz

Он массивы перебирает, а их 3.

совершенно точно.

По поводу eval-а я вроде разобрался, просто потерялся в скобках и кавычках.
Если без eval, то в MASSIV будет залетать: («${mas1[@]}») потом («${mas2[@]}») и («${mas3[@]}»).
Если с eval, то («${mas1[@]}») будет выполняться как команда, то есть будет поэлементная запись одних элементов массива mas в массив MASSIV, как раз то что нужно.
Получается так, что:
двойные кавычки - нужны что бы пробелы между буквами убрать.
({}) - нужны для записи одного массива в другой.
Если без eval и внутренних одинарных то не подставляются переменные $per$i, если без внешних то пишет bad substitution.

v4567 ★★
() автор топика
Последнее исправление: v4567 (всего исправлений: 1)
Ответ на: комментарий от v4567

совершенно точно.

Не ленитесь, комментируйте автору.

двойные кавычки - нужны что бы пробелы между буквами убрать.

Pardon? В данном случае это магический синтаксис shell-а, в двойных кавычках с @, зарезервировано для действия: вывести все элементы в виде отдельных строк. Так как имя массива формируется программно, а shell из-за дурацкого синтаксиса не позволяет выполнить вложенность внутри ${}, то используется eval, а следовательно, чтобы произошло формирование команды в строке, все спец-символы кроме имени из переменных, в том числе двойные кавычки заключены в одинарные кавычки. При желании можно вместо одинарных использовать обратный слеш - \, то смотрится это ещё хуже.

vodz ★★★★★
()
Ответ на: комментарий от v4567

К сожалению, я не преподаю, а сам учился вот уже за 30 перевалило и даже не помню, по русски или нет. Одно могу сказать, что учиться bash-у также неправильно, как учиться MS Word и т.п. Надо читать об общем синтаксисе shell, башизмы они такие, могут поменяться в следующей версии.

vodz ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.