Bash 스크립트에서 다른 변수 이름을 기반으로 변수에 대한 참조를 만드시겠습니까? [복사]

Bash 스크립트에서 다른 변수 이름을 기반으로 변수에 대한 참조를 만드시겠습니까? [복사]

Bash 스크립트에 다음 변수가 있다고 가정해 보겠습니다.

path_family="/home/family"
path_family_log="/var/log/family.log"
path_friends="/home/friends"
path_friends_log="/var/log/friends.log"
path_pets="/home/pets"
path_pets_log="/var/log/pets.log"

다음과 같은 작업을 수행할 수 있는 for 루프를 만들고 싶습니다.

for TYPE in family friends pets
do
  for FILE in $path_<TYPE>
  do
    cat $FILE >> $path_<TYPE>_log
  done
done

분명히 이것은 올바른 코드가 아니며 단지 내가 원하는 것을 표현하는 가장 직접적인 방법일 뿐입니다. 변수 이름에 하위 문자열 대체를 수행하고 예상대로 작동하도록 하는 방법을 알아내려고 머리를 쥐어짜고 있습니다.

답변1

대신 연관 배열을 사용하는 것이 좋습니다.

#! /bin/bash -
typeset -A dir log # declare both variables as associative arrays
dir=(
   [family]=/home/family
  [friends]=/home/friends
     [pets]=/home/pets
)
log=(
   [family]=/var/log/family.log
  [friends]=/var/log/friends.log
     [pets]=/var/log/pets.log
)
for type in "${!dir[@]}"
do
  cat -- "${dir[$type]}/somefile" >> "${log[$type]}"
done

( "${!array[@]}"배열 키 목록을 검색하기 위한 ksh 구문입니다(특정 순서 없음).

또는 zsh(bash보다 수십 년 전에 연관 배열이 있음)에서 더 명확하게 설명하면 다음과 같습니다.

#! /bin/zsh -
typeset -A dir log
dir=(
  family  /home/family
  friends /home/friends
  pets    /home/pets
)
log=(
  family  /var/log/family.log
  friends /var/log/friends.log
  pets    /var/log/pets.log
)
for type in ${(k)dir}
do
  cat -- $dir[$type]/somefile >> $log[$type]
done

ksh93(bash가 연관 배열 구문을 차용한 것)을 사용하면 복합 변수의 연관 배열을 사용할 수도 있습니다.

#! /bin/ksh93 -
conf=(
   [family]=(dir=/home/family;  log=/var/log/family.log)
  [friends]=(dir=/home/friends; log=/var/log/friends.log)
     [pets]=(dir=/home/pets;    log=/var/log/pets.log)
)
for type in "${!conf[@]}"
do
  cat -- "${conf[$type].dir}/somefile" >> "${conf[$type].log}"
done

답변2

제공한 변수를 기억하면 아래 코드를 통해 원하는 결과를 얻을 수 있습니다. 이것이 현재와 미래에 귀하와 다른 사람들에게 도움이 되기를 바랍니다.

여러 줄을 배쉬하세요:

for TYPE in family friends pets 
do  
    for FILE in $(eval echo "\$path_$TYPE/*")
    do 
        cat $FILE >> $(eval echo "\$path_${TYPE}_log")
    done
done

단일 라이너

for TYPE in family friends pets ;do  for FILE in $(eval echo "\$path_$TYPE/*"); do cat $FILE >> $(eval echo "\$path_${TYPE}_log") ;done ; done

관련 정보