Intereting Posts

для каждого с массивом с несколькими элементами

Я работаю над скриптом, который загружает вещи.

В сценарии мне нужно сопоставить имя и URL, которые будут загружаться повторно (отсюда и сценарий)

name1,url1 name2,url2 name3,url3 command $NAME $URL 

Поэтому я хочу, чтобы для каждого цикла использовался мой список имен и соответствующих URL-адресов. Каков наилучший способ сделать это? На данный момент не интересно хранить эти списки во внешнем файле или что-то еще. В сценарии я хотел бы это сделать для этого примера.

bash довольно ограничен на этом фронте. Вы можете попробовать другие оболочки.

С zsh (вы уже используете синтаксис zsh как вы не указали свои переменные в command $NAME $URL ):

 for name url ( name1 url1 name2 url2 name3 url3 ) command $name $url 

С помощью bash или другой оболочки POSIX вы можете:

 while IFS=, read <&3 -r name url; do { command "$name" "$url" } 3<&- done 3<< "EOF" name1,url1 name2,url2 name3,url3 EOF 

Это означает, что значения не могут содержать запятые или символы новой строки.

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

 typeset -A pairs pairs=( [name1]=url1 [name2]=url2 [name3]=url3 ) for name in "${!pairs[@]}"; do url=${pairs[$name]} command "$name" "$url" done 

Это также будет работать в ksh93 . Остерегайтесь, что правила цитирования немного отличаются между ними. В zsh синтаксис определения ассоциативного массива более прост и применяются обычные правила цитирования:

 pairs=(name1 url1 name2 url2 name3 url3) 

Который вы можете использовать в нескольких строках:

 pairs=( name1 url1 name2 url2 name3 url3 ) 

Остерегайтесь того, что порядок не сохраняется, и что ассоциативные массивы bash не поддерживают пустой ключ.

ksh93 поддерживает многомерные массивы, поэтому вы можете сделать:

 pairs=((name1 url1) (name2 url2) (name3 url3)) for ((i = 0; i < ${#pairs[@]}; i++)); do name=${pairs[i][o]} url=${pairs[i][1]} command "$name" "$url" done 

Вы можете создать здесь-документ, который был записан во временный файл, а затем обработан. Временный файл будет автоматически удален, поэтому ручная очистка не требуется.

 #!/bin/bash mylist=/var/tmp/$$ trap 'rm -f ${mylist}' EXIT cat << _EOF_ > ${mylist} name1 url1 name2 url2 name3,url3 _EOF_ while read name url do printf "%s %s\n" ${name} ${url} done < ${mylist} 

В начале я отвел свой разум к чему-то сложному, как ассоциативные массивы.
Затем я понял, что это можно сделать так же легко, как и рев, учитывая, что у вас столько имен, как URL:

 root@debian:a=( "name1,url1" "name2,url2" "name3,url3" );while IFS="," \ read -r name url;do echo "command $name $url";done<<<$(printf '%s\n' "${a[@]}") command name1 url1 command name2 url2 command name3 url3 

Все, что вам нужно, это хранить имена и URL-адреса в одном массиве (a в моем тесте) вместе, разделенные, то есть запятыми.

Возможно, простой скрипт bash будет работать для вас:

 pairs=( "name1,url1" "name2,url2" "name3,url3" ) for pair in "${pairs[@]}"; do IFS=, read name url <<<"${pair}" printf "%s %s\n" "${name}" "${url}" command "${name}" "${url}" done 

Немного чересчур сложный в своем собственном праве, но придерживаясь формата, который дал большинство других, но не вызывает IFS, который я бы использовал

 pairs=( "name1,url1" "name2,url2" "name3,url3" ) for pair in "${pairs[@]}"; do #Create an array in itself, of the two values. tmpArr=(`echo $pair | tr ',' ' '`) #Then either use Array Indexing on the array ie. #Or place the offsets in their own variables. ie Run=${tmpArr[0] ...; command ${tmpArr[0]} ${tmpArr[1]} done 

Устраняет необходимость в Temporary Files, никакой реальной очистки не требуется, если используется в сценарии, который первоначально был Sha-Bang, или сделан локальным в функции, что я сделал большую часть своих сценариев, сохраняя синтаксис как можно ближе к «C», насколько это возможно. Палочки к моему девизу bash также: «Если вы хотите сделать это, кто-то сделал это раньше, и сделал его модулем, поэтому не выполняйте работу …»