연도별로만 다른 배열을 생성하고 싶습니다. 루프에서 중괄호 확장 및 변수를 사용하여 배열을 만듭니다.
나는 성공하지 못한 채 다음 코드를 시도했습니다.
LIST={JF,JFE,RFS,JBF,JFI,JMCB}
for year in {1998..2000} {2009..2011}
do
declare -a 'y$year=('"$LIST"'-$year)'
echo "${y$year[@]}"
done
결과는 다음 항목의 목록이어야 합니다.
y1998: JF-1998 JFE-1998 RFS-1998 JBF-1998 JFI-1998 JMCB-1998
y1999: JF-1999 JFE-1999 RFS-1999 JBF-1999 JFI-1999 JMCB-1999
...
y2011: JF-2011 JFE-2011 RFS-2011 JBF-2011 JFI-2011 JMCB-2011
인쇄할 필요가 없으며 루프에서 사용하고 매개변수로 전달하기만 하면 됩니다. 두 번째 때문에 eval
in-loop로는 충분하지 않습니다.
답변1
중괄호 확장을 연기하는 것은 실제로 다음의 예입니다.eval
, 특히 문자열화를 원하는 경우 -일반적인 매개변수 확장은 올바른 작업을 수행하지 않습니다.적시에.
이렇게 하면 원하는 작업이 수행됩니다.
LIST={JF,JFE,RFS,JBF,JFI,JMCB}
for year in {1998..2000} {2009..2011}
do
eval "y$year=($LIST-$year)"
tmp="y$year[@]"
echo "${!tmp}"
done
eval
배열에 간접적으로 접근할 수 없으므로, 인쇄하려면 배열 내부를 문자열화해야 합니다. 그렇지 않으면 그 이후의 모든 것을 꺼낼 수 있습니다 ;
.tmp
에 사용됩니다간접 확장: 해당 값으로 대체되는 로 설정되면 이 반복이 주어진 배열의 내용으로 확장됩니다 tmp
( 등 은 무엇으로 확장됩니다)."y$year[@]"
$year
${!tmp}
${y1998[@]}
위의 내용은 다음과 같이 출력됩니다.
JF-1998 JFE-1998 RFS-1998 JBF-1998 JFI-1998 JMCB-1998
JF-1999 JFE-1999 RFS-1999 JBF-1999 JFI-1999 JMCB-1999
JF-2000 JFE-2000 RFS-2000 JBF-2000 JFI-2000 JMCB-2000
JF-2009 JFE-2009 RFS-2009 JBF-2009 JFI-2009 JMCB-2009
JF-2010 JFE-2010 RFS-2010 JBF-2010 JFI-2010 JMCB-2010
JF-2011 JFE-2011 RFS-2011 JBF-2011 JFI-2011 JMCB-2011
그리고 배열을 생성합니다 y1998
.... y2011
이러한 declare
s는 반드시 필요한 것은 아니지만, eval
문자열화가 필요하지 않고 원할 경우 건너뛸 수 있습니다.
내 생각에 그것은 아마도 당신이 진정으로 원하는 기본 목표를 달성하는 방법이 아닐 것입니다. 중첩 루프는 나쁘지 않습니다. 루프의 어떤 지점이라도 하드코딩되어 있으면 추상화할 수 있습니다.
답변2
이것은 한 가지 방법입니다(지원 확장 포함):
unset y _y
for y in {JF,JFE,RFS,JBF,JFI,JMCB,}-{{1998..2000},{2009..2011}}
do case "${_y=y${y#*-}[@]}" in
(y${y#-}*) echo "${!_y}" ;;
(*) declare -a "${_y%???}+=($y)";;
esac; unset y _y; done
그러면 루프의 매개변수 세트가 for
필요한 모든 값으로 확장됩니다.추가하다추가 마지막 그룹에는 연도만 포함됩니다. 이 일을 하는 모든 사람을 위해아니요숫자로 시작하여 발생하는 모든 항목 declare
에 배열 구성원을 추가 y${y##*[!0-9]}
하고 각 숫자에 대해하다, echo
인쇄하세요.
따라서 처음 36번의 반복에서는 각 배열을 작성하고 다음 6번의 반복에서는 각 배열을 인쇄합니다. 출력은 다음과 같습니다
JF-1998 JFE-1998 RFS-1998 JBF-1998 JFI-1998 JMCB-1998
JF-1999 JFE-1999 RFS-1999 JBF-1999 JFI-1999 JMCB-1999
JF-2000 JFE-2000 RFS-2000 JBF-2000 JFI-2000 JMCB-2000
JF-2009 JFE-2009 RFS-2009 JBF-2009 JFI-2009 JMCB-2009
JF-2010 JFE-2010 RFS-2010 JBF-2010 JFI-2010 JMCB-2010
JF-2011 JFE-2011 RFS-2011 JBF-2011 JFI-2011 JMCB-2011
여기에 대안이 있습니다. 아마도 ...
for year in 1998 1999 2000 2009 2010 2011
do printf "%s-$year " JF JFE RFS JBF JFI JMCB
echo; done
이것은 적어도 동일한 출력을 제공합니다. 또한 배열에 저장하면 가능합니다.
for year in 1998 1999 2000 2009 2010 2011
do declare -a "y$year=($(printf "%s-$year " JF JFE RFS JBF JFI JMCB |
tee /dev/fd/2 ))"
year=y$year[@]; year=(${!year})
echo "${#year[@]}"
done 2>&1; unset year
이것은 두 번째 명령의 출력이지만 첫 번째 명령은 6과 동일한 내용을 인쇄합니다. 이는 단지 배열 구성원 수를 나타냅니다.
JF-1998 JFE-1998 RFS-1998 JBF-1998 JFI-1998 JMCB-1998 6
JF-1999 JFE-1999 RFS-1999 JBF-1999 JFI-1999 JMCB-1999 6
JF-2000 JFE-2000 RFS-2000 JBF-2000 JFI-2000 JMCB-2000 6
JF-2009 JFE-2009 RFS-2009 JBF-2009 JFI-2009 JMCB-2009 6
JF-2010 JFE-2010 RFS-2010 JBF-2010 JFI-2010 JMCB-2010 6
JF-2011 JFE-2011 RFS-2011 JBF-2011 JFI-2011 JMCB-2011 6
기억하세요. 이것은 declare
명령이고 var$expand=(something $expand)
인수는 단지 인수일 뿐입니다. declare
의 매개변수는 다른 매개변수와 동일한 방식으로 확장됩니다. 이는 var$expand=$expand
명령문의 경우에는 해당되지 않습니다. 따라서 declare
간접적으로 하는 것과 같은 방식으로 간접적으로 할 수 있습니다 export
. 제 생각에는 당신이 사용한 어려운 인용문은 불필요하다고 생각합니다.
답변3
중괄호 확장을 통해 배열로 변환합니다 set --
.
그런 다음 출력을 구성하는 간단한 2D 루프가 있습니다.
set -- {JF,JFE,RFS,JBF,JFI,JMCB}
for year in {1998..2000} {2009..2011}; do
printf "y%s: " $year
for code do
printf "%s-%s " $code $year
done
echo
done
생산하다:
y1998: JF-1998 JFE-1998 RFS-1998 JBF-1998 JFI-1998 JMCB-1998
y1999: JF-1999 JFE-1999 RFS-1999 JBF-1999 JFI-1999 JMCB-1999
y2000: JF-2000 JFE-2000 RFS-2000 JBF-2000 JFI-2000 JMCB-2000
y2009: JF-2009 JFE-2009 RFS-2009 JBF-2009 JFI-2009 JMCB-2009
y2010: JF-2010 JFE-2010 RFS-2010 JBF-2010 JFI-2010 JMCB-2010
y2011: JF-2011 JFE-2011 RFS-2011 JBF-2011 JFI-2011 JMCB-2011