연관 배열

연관 배열

사용자 입력 후 배열에서 선택한 변수의 확장된 값에 대해 작업을 수행하고 싶습니다. 이것이 내가 의미하는 바입니다:

$ ./myscript.sh url2


#!/bin/bash

array=(Sigil wp2epub csskit)

Sigil       =   "https://github.com/Sigil-Ebook/Sigil.git"
csskit      =   "https://github.com/mattharrison/epub-css-starter-kit.git"
wp2epub     =   "https://github.com/mrallen1/wp2md.git"

if [ -z $1 ]; then
  echo "This script needs at least one parameter!"
  exit 1
fi

if [ $1 = Sigil ]; then
  ans=$Sigil # expanded
elif [ $1 = csskit ]; then
  ans=$csskit # expanded
elif [ $1 = wp2epub ]; then
  ans=$wp2epub # expanded
else
  echo "Please inform one of \
        Sigil, csskit or wp2epub!"
fi

git clone $ans

설명하다:

스크립트는 사용자 입력($1)을 확인하고 이를 가능한 변수의 배열과 비교하고, 발견되면 해당 변수의 확장된 값을 답변으로 검색한 다음 확장된 값(변수 이름 대신)을 사용합니다.

며칠 동안 노력했지만 제한된 bash 스크립팅 기술만으로는 충분하지 않습니다.

미리 감사드립니다.


@terdon 요청에 따라: 사용자가 인간 친화적인 배열의 변수 이름을 알려주기를 바랍니다.

이러한 변수는 실제로 github(git clone)에서 가져온 다음 다시 컴파일하고 다시 설치해야 하는 패키지의 이름입니다.

실제 사용량은 다음과 같습니다.

$ ./update.sh Sigil # Sigil is one of the variables

답변1

연관 배열을 사용하십시오.

#!/bin/bash

declare -A url
url=( [url1]="http://www.google.com"
      [url2]="http://www.yahoo.com"
      [url3]="http://www.bing.com"
    )

if [[ -z $1 ]] ; then
    echo "This script needs at least one parameter!"
    exit 1
elif [[ -z ${url[$1]} ]] ; then
    echo 'Unknown option'
    exit 1
fi

echo "Let's search ${url[$1]}."

답변2

제공한 스크립트에서 $1an에는 옵션 이름이 포함되고 an에는 $array옵션 값이 포함됩니다. 요청에 따라 확장된 변수로 결과를 얻으려면 다음과 $ans같은 몇 가지 옵션이 있습니다.

평가하다

eval: 예를 들어 $1을 확장 하고 ans에 Sigil할당합니다 .$Sigil

eval ans\=\"\$\{"$1"\}\"

그러나 이는 $1변수에 대한 한 단어 레이블이라고 가정합니다. 입력에 다른 콘텐츠가 있으면 평가될 수 있습니다. 보다 강력한 솔루션은 ${array[i]}배열의 내용이 스크립트에 의해 제어되므로 eval 대신 대안을 사용하는 것입니다.

간접적인

Bash의 비슷한 관용구 ${!1}는 var 가 가리키는 값을 얻는 것인데 $1, 이것이 바로 우리에게 필요한 것입니다. 다시 한 번 더 강력하게 사용하십시오( ${array[i]}일치하는 항목이 발견되면:$array[i]

a="array[i]"; ans="${!a}"

연관 배열

그러나 배열 키와 배열 값에 연관 배열을 사용하면 모든 평가 및 간접 문제를 피할 수 있습니다.

그러면 올바른 값을 쉽게 찾을 수 있습니다. 배열에 값이 있으면 유효한 값입니다. 배열에 키 값이 없으면 해당 키는 유효하지 않습니다.

이 개념을 기반으로 한 전체 스크립트는 다음과 같습니다.

#!/bin/bash

[ $# -lt 1 ] && {  echo "This script needs at least one parameter!"; exit 1; }

declare -A a
    a=(
    [Sigil]="https://github.com/Sigil-Ebook/Sigil.git"
    [wp2epub]="https://github.com/mattharrison/epub-css-starter-kit.git"
    [csskit]="https://github.com/mrallen1/wp2md.git"
    )


### Process an error while informing of options.
for    val in "${!a[@]}"
do     d=$d${d:+", "}$last
       last=$val
done
d="Please inform one of $d or $last"
SayError(){ echo "$d" >&2; exit 1; }



### Process a valid command execution.
ExecCmd(){ git clone "$ans"; }



### Process all arguments of script.
for    arg
do     unset ans                          ### unset result variable.
       printf -v ans '%s' "${a[$arg]}"    ### Assign result to "$ans"
       ${ans:+:} SayError                 ### If "$ans" is empty, process error.
       ${ans:+false} || ExecCmd           ### With valid "$ans" execute command.
done

이를 제거하기 위해 SayError 함수를 변경할 수 exit 1있으며 스크립트는 여전히 모든 인수를 처리하고 유효하지 않은 값에 대해 경고합니다.

답변3

arr=($url1 $url2 $url3)

for i in ${arr[@]}; do
  if [[ $i == $1 ]] ;then
    ans=$i
    break
  fi
done

관련 정보