루프에서 중괄호 확장을 사용하여 배열 만들기

루프에서 중괄호 확장을 사용하여 배열 만들기

연도별로만 다른 배열을 생성하고 싶습니다. 루프에서 중괄호 확장 및 변수를 사용하여 배열을 만듭니다.

나는 성공하지 못한 채 다음 코드를 시도했습니다.

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

인쇄할 필요가 없으며 루프에서 사용하고 매개변수로 전달하기만 하면 됩니다. 두 번째 때문에 evalin-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이러한 declares는 반드시 필요한 것은 아니지만, 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

관련 정보