아래 코드에서는 루프에 몇 가지 연관 배열을 만듭니다. 이는 문자열 식별자와 연도라는 두 개의 문자열로 구성됩니다. 일단 생성되면 식별자만을 기반으로 루프에서 배열에 액세스하고 싶습니다.
#!/bin/bash
# Declare associative arrays of journal-year combinations
A_JOURNAL_LIST={JF,JFE,RFS}
B_JOURNAL_LIST={JBF,JFI,JMCB}
ALL_JOURNAL_LIST={JF,JFE,RFS,JBF,JFI,JMCB}
for year in {1998..2000} {2009..2011}
do
eval "A_$year=($A_JOURNAL_LIST-$year) ;"
eval "B_$year=($B_JOURNAL_LIST-$year) ;"
eval "all_$year=($ALL_JOURNAL_LIST-$year) ;"
done
A_1999
JF-1999 JFE-1999 RFS-1999
여기에서는 예를 들어 다음과 같이 확장되는 여러 배열을 쉽게 얻을 수 있습니다 .
for journal in A B all
do
echo "${'$journal'_1999[@]}"
done
기대했다
JF-1999 JFE-1999 RFS-1999
JBF-1999 JFI-1999 JMCB-1999
JF-1999 JFE-1999 RFS-1999 JBF-1999 JFI-1999 JMCB-1999
나는 bad substitution error
항상 하나를 얻고 많은 조합을 시도합니다. 뭐가 문제 야?
답변1
에 오신 것을 환영합니다eval
지옥! 한번 사용하기 시작하면 절대로 제거할 수 없습니다.
for journal in A B all
do
eval "echo \"\${${journal}_1999[@]}\""
done
이 작업을 수행하는 더 좋은 방법이 있을 수 있지만 쉘 스크립트에서 연관 배열이나 다른 중첩 배열을 사용하는 것을 결코 귀찮게 하지 않습니다. 이러한 데이터 구조가 필요한 경우 기본적으로 이를 지원하는 스크립팅 언어를 사용하는 것이 더 나을 수 있습니다.
실제로 bash는 연관 배열을 어느 정도 지원합니다. 그들이 당신을 위해 작동하는지 여부는 또 다른 질문입니다. 어쨌든 다른 쉘로 이식 가능하지 않습니다.
답변2
가변 간접여기에 도움이 될 것입니다:
for journal in A B all
do
indirect="${journal}_1999[@]"
echo "$journal: ${!indirect}"
done
산출
A: JF-1999 JFE-1999 RFS-1999
B: JBF-1999 JFI-1999 JMCB-1999
all: JF-1999 JFE-1999 RFS-1999 JBF-1999 JFI-1999 JMCB-1999
평가를 다시 작성할 필요가 없습니다. 배열의 배열은 bash가 기본적으로 제공하는 것이 아니므로 공백으로 구분된 문자열과 임시 저장소를 사용해야 합니다.
# Declare associative arrays of journal-year combinations
a_journal_list=( {JF,JFE,RFS} )
b_journal_list=( {JBF,JFI,JMCB} )
all_journal_list=( "${a_journal_list[@]}" "${b_journal_list[@]}" )
declare -a a b all
for year in {1998..2000} {2009..2011}
do
# store year-specific values as space-separated strings
a[$year]=$( printf "%s-$year " "${a_journal_list[@]}" )
b[$year]=$( printf "%s-$year " "${b_journal_list[@]}" )
all[$year]=$( printf "%s-$year " "${all_journal_list[@]}" )
done
selected_years=( 1998 1999 2000 )
for journal in a b all
do
# I'll use the positional params for temp storage of the accumulated array
set --
for year in "${selected_years[@]}"
do
indirect="${journal}[$year]"
# variable is unquoted to allow word splitting
set -- "$@" ${!indirect}
done
echo $journal
printf "%s\n" "$@"
done
답변3
Bash의 배열에 대해 몇 가지 오해가 있다고 생각합니다.
정렬
Bash provides one-dimensional indexed and associative array variables. Any variable may be used as an indexed array; the declare builtin will explicitly declare an array. There is no maximum limit on the size of an array, nor any requirement that members be indexed or assigned contiguously. Indexed arrays are referenced using integers (including arithmetic expressions) and are zero-based; associative arrays are referenced using arbitrary strings. Unless otherwise noted, indexed array indices must be non-negative integers. An indexed array is created automatically if any variable is assigned to using the syntax name[sub‐ script]=value. The subscript is treated as an arithmetic expression that must evaluate to a number. To explicitly declare an indexed array, use declare -a name (see SHELL BUILTIN COMMANDS below). declare -a name[subscript] is also accepted; the subscript is ignored. Associative arrays are created using declare -A name. Attributes may be specified for an array variable using the declare and readonly builtins. Each attribute applies to all members of an array. Arrays are assigned to using compound assignments of the form name=(value1 ... valuen), where each value is of the form [subscript]=string. Indexed array assignments do not require anything but string. When assigning to indexed arrays, if the optional brackets and subscript are supplied, that index is assigned to; otherwise the index of the element assigned is the last index assigned to by the statement plus one. Indexing starts at zero. When assigning to an associative array, the subscript is required. This syntax is also accepted by the declare builtin. Individual array elements may be assigned to using the name[subscript]=value syntax introduced above. When assigning to an indexed array, if name is subscripted by a negative number, that number is interpreted as relative to one greater than the maximum index of name, so negative indices count back from the end of the array, and an index of -1 references the last element.