Создать текст, соответствующий нескольким назначениям переменных из одной переменной

Создать текст, соответствующий нескольким назначениям переменных из одной переменной

У меня есть переменная, которая имеет такое значение

line=dog,/path1,/path2

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

dog=/path1,/path2
dog1=/path1
dog2=/path2

Аналогично, если у меня есть, line=bull,/val1,/val2мне нужен следующий вывод

bull=/val1,/val2
bull1=/val1
bull2=/val2

Обратите внимание, что lineбудет только три значения, разделенные запятыми.

решение1

Я думаю, это именно то, что вы пытаетесь сделать:

line='dog,/path1,/path2'
IFS=', ' read -r -a dog <<< "$line"

echo "$dog"
dog
echo "${dog[1]}"
/path1
echo "${dog[2]}"
/path2 

Предполагается, что ваша оболочка — bash.

решение2

Вот решение, ориентированное на bash:

IFS=, read -r -a vars <<<"$line"
printf "%s\n" "${vars[0]}=${vars[1]},${vars[2]}" "${vars[0]}1=${vars[1]}" "${vars[0]}2=${vars[2]}"

Первая строка разбивает вашу $lineпеременную на части на основе запятых. Вторая строка, работающая изнутри наружу:

  1. выводит первое значение (например, «собака»), знак равенства, затем вторые два значения,
  2. выводит первое значение с суффиксом 1, знаком равенства, затем второе значение,
  3. выводит первое значение, дополненное 2знаком равенства, затем третье значение,
  4. printfэти три строки, разделенные символами новой строки.

Этот ответ, как и ваш вопрос, жестко запрограммирован на наличие трех значений в $line.

Пример ввода и вывода (в начале $— приглашения оболочки):

$ line=dog,/path1,/path2
$ IFS=, read -r -a vars <<<"$line"
$ printf "%s\n" "${vars[0]}=${vars[1]},${vars[2]}" "${vars[0]}1=${vars[1]}" "${vars[0]}2=${vars[2]}"
dog=/path1,/path2
dog1=/path1
dog2=/path2

Вы можете достаточно легко перенаправить вывод printf в файл.

решение3

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

$ line=dog,/path1,/path2

$ newline=$(printf "%s\n" "$line" | 
            perl -n -e 'BEGIN {$count=1};
                        my ($var,@values) = split /,/;
                        print "$var=" . join(",",@values);
                        foreach (@values) {
                            printf "%s%i=\"%s\" ",$var, $count++, $_
                        }')

$ echo "$newline"
dog=/path1,/path2 dog1=/path1 dog2=/path2

$ declare $newline

$ declare | grep '^dog'
dog=/path1,/path2
dog1=/path1
dog2=/path2

Это используется perlдля разделения $lineзапятыми. Первое поле сохраняется в $var, остаток в массиве с именем @values. Затем он создает вывод, подходящий для использования с командой bash declareдля установки переменных.

Обратите внимание, что $newlineэто не и не должно быть заключено в двойные кавычки в declareстроке. Если это заключено в двойные кавычки, declareто будет получен только один аргумент, а не три, разделенные пробелами.

Одним из неприятных побочных эффектов отсутствия цитирования здесь является то, чтоdeclare ВОЛЯтерпеть неудачу, если какое-либо из значений поля содержит пробелы и т. д. например line=dog,/path /with / spaces,/path2. Вы можете исправить это, если требуется, выведя соответствующие кавычки из операторов printи printfв perlскрипте. И/или определив $newlineкак массив bash вместо строки. Оставлено в качестве упражнения для читателя, поскольку я уже достаточно показал принцип/метод, используемый здесь.

Если вы хотите объявить их как экспортируемые переменные, используйте:

declare -x $newline

help declareдля более подробной информации см .

Кстати, в kshможно использовать typesetвместо declare. typesetтакже поддерживается, bashно считается устаревшим (см. help typesetв bash).


Наконец: вы уверены, что не предпочли бы использовать переменную-массив оболочки (например dog[0]=/path1,/path2, dog[1]=/path1, и dog[2]=/path2) вместо отдельных переменных? Именно для таких вещей они и существуют.

решение4

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

line="dog,/path1,/path2"
first="$(echo "${line}" | awk -F, '{ print $1 }')"
eval "${first}1=$(echo "${line}" | awk -F, '{ print $2 }')"
eval "${first}2=$(echo "${line}" | awk -F, '{ print $3 }')"

echo "${dog1}"
/path1
echo "${dog2}"
/path2

Связанный контент