Bash - l oop через массив объектов и объединить их - PullRequest
0 голосов
/ 20 января 2020

Я пытаюсь создать for-l oop до go через все элементы массива и добавить элементы в строку. Теги задаются в виде единой строки в формате «tag1 tag2 tag3», а параметр tagging может задаваться столько раз, сколько я хочу, с помощью одной команды с синтаксисом «-tag tag1 -tag -tag2 -tag tag3». Я не могу создать для l oop для этой работы, и меня немного смущает, что не так с моим кодом.

TAGS="asd fgh jkl zxc bnm" # Amount of tags varies, but there is always at least one
ARRAY=($TAGS)
TAGSTOBEADDED=""
for i in "$ARRAY[@]"
do
  STRINGTOBEADDED="-tag ${ARRAY[$i]}"
  $TAGSTOBEADDED=$TAGSTOBEADDED+$STRINGTOBEADDED
done
command $TAGSTOBEADDED

Ответы [ 2 ]

0 голосов
/ 21 января 2020

Во-первых: избегайте хранения списков вещей в разделенных пробелами строках (как вы в настоящее время делаете с TAGS и TAGSTOBEADDED) - есть куча вещей, которые могут go ошибаться, если они есть " забавные персонажи (или если IFS меняется). Вместо этого используйте массив. Хранение их как строки и последующее преобразование не помогает; все те же потенциальные проблемы возникают во время преобразования.

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

tags=(asd fgh jkl zxc bnm)

У вас также есть ряд синтаксических ошибок в скрипте. В этой строке:

for i in "$ARRAY[@]"

... оболочка попытается развернуть $ARRAY как простую переменную (не массив), а затем обработать "[@]" как просто некоторые не связанные символы, которые go после него. Вам необходимо заключить скобки в переменную refence (например, "${ARRAY[@]}") каждый раз, когда вы делаете что-то нетривиальное со ссылкой на переменную. Кстати, эта идиома - включая двойные кавычки, фигурные скобки, квадратные скобки и знак-знак - это то, что вы почти всегда хотите получить при получении содержимого массива.

В этой строке:

STRINGTOBEADDED="-tag ${ARRAY[$i]}"

$i будет расширен до одного из элементов массива, не его индекса. То есть он расширится до чего-то вроде:

STRINGTOBEADDED="-tag ${ARRAY[asd]}"

... что не имеет никакого смысла. Вы просто хотите

STRINGTOBEADDED="-tag $i"

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

$TAGSTOBEADDED=$TAGSTOBEADDED+$STRINGTOBEADDED

Здесь есть две проблемы: вам не нужен знак доллара для переменной, назначаемой ($varname получает значение переменной; всякий раз, когда вы ее устанавливаете, не используйте $). Также + не требуется для добавления строк, вы просто вставляете их в конец. Ну, вам нужно добавить пробел между ними, что-то вроде этого:

TAGSTOBEADDED=$TAGSTOBEADDED" "$STRINGTOBEADDED
TAGSTOBEADDED="$TAGSTOBEADDED $STRINGTOBEADDED"

(Как правило, вы должны иметь двойные кавычки вокруг всех ссылок на переменные; справа от простого присваивания это одно из немногих мест, где можно безопасно оставлять их без кавычек, но я предпочитаю всегда просто заключать в кавычки, а не пытаться запомнить все исключения о том, где это безопасно, а где нет. Плюс, цитируя только пробел выглядит странно.)

Но вы тоже не хотите этого делать, потому что (опять же) разделенные пробелами строки - плохой способ сделать что-то. Используйте массив. Поэтому перед l oop создайте пустой массив вместо пустой строки:

tagstobeadded=()

... и затем внутри l oop добавьте к нему +=( ):

tagstobeadded+=(-tag "$i")

... и затем в конце используйте его со всеми соответствующими кавычками, фигурными скобками и т. Д. c:

command "${tagstobeadded[@]}"

Итак, со всеми этими изменениями вот что я рекомендую:

tags=(asd fgh jkl zxc bnm)
tagstobeadded=()
for i in "${tags[@]}"
do
  tagstobeadded+=(-tag "$i")
done
command "${tagstobeadded[@]}"
0 голосов
/ 20 января 2020

Во-первых, синтаксис вашего массива неверен, как сказал @oguz ismail. Для перемещения по элементам массива вы должны использовать это:

for i in "${ARRAY[@]}"; { echo $i;}

Секунда $TAGSTOBEADDED=$TAGSTOBEADDED+$STRINGTOBEADDED, это также не удалось. Переменные установлены следующим образом: var="$var 123" вам не нужно $ перед именем переменной, если вы хотите изменить его. Вернуться к коду. В этом примере вам даже не нужен массив, просто используйте TAGS var (без ""):

for i in $TAGS; { TAGSTOBEADDED+="-tag $i"; }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...