주어진 매개변수가 주어진 배열에 있는지 확인하는 방법은 무엇입니까?

주어진 매개변수가 주어진 배열에 있는지 확인하는 방법은 무엇입니까?

script.sh다음과 같은 쉘 스크립트가 있습니다.

names=( jack john jerry)

사용자가 다음과 같이 첫 번째 인수로 이 세 가지 이름 중 하나를 입력하기를 원합니다.

./script.sh jack

예를 들어 사용자가 문자를 잘못 입력한 경우

./script.sh kate

이는 a를 실행 exit하고 사용자에게 이 3개 중 하나만 입력하도록 요청합니다.

어떻게 해야 합니까?

답변1

names=(jack john jerry); 
if [[ " "${names[@]}" " == *" "$1" "* ]] ;then 
    echo "$1: ok"
else 
    echo "$1: not recognized. Valid names are:"
    echo "${names[@]/%/,}"
    exit 1
fi

위의 코드는 공백을 포함하지 않는 이름에 작동합니다.
아래 수정된 버전은 이름의 공백을 처리합니다.

names=("flash jack" john jerry); 
d=$'\1'   # validation delimiter - value is \x01
valid="${names[@]/%/$d}"
valid="$d${valid//$d /$d}"
if [[ $valid == *$d$1$d* ]] ;then 
    echo "$1: ok"
else 
    echo "$1: not recognized. Valid names are:"
    echo "${names[@]/%/,}"
    exit 1
fi

공백 인식 버전의 출력:

flash jack: ok

또는

kate: not recognized. Valid names are:
flash jack, john, jerry,

답변2

이것이 바로 case선언의 목적입니다:

#! /bin/bash

case $1 in
    [Jj]ack)
        echo "You chose Jack!"
    ;;
    [Jj]ohn)
        echo "You chose John!"
    ;;
    [Jj]erry)
        echo "You chose Jerry!"
    ;;
    ## For all other cases
    *)
        echo 'Please choose one of "John", "Jack" or "Jerry"' >&2
    exit 1
esac

$1Case 문은 스크립트에 전달된 첫 번째 인수 값을 기반으로 실행됩니다. jack또는 이면 Jack첫 번째 선택이 실행되고, 또는이면 Johnjohn번째 선택이 실행됩니다. 다른 항목을 입력하면 마지막 문이 실행됩니다.

답변3

먼저, 충분히 강력한 쉘 스크립트는 악마의 작업으로 간주될 수 있는 괴물 같은 배열 구현을 사용할 수 있다는 점을 언급해야 합니다. 또한 어떤 쉘인지 표시하지 않았지만 bash라고 가정합니다.

이를 수행하는 방법에는 여러 가지가 있지만 모두 보기 흉합니다.

1) 배열을 반복합니다. 읽기 쉽고 비교적 깨끗하지만 비효율적입니다.

for i in 0 1 2 3 4
do
echo compare ${ARRAY[$i]} perhaps using test or whatever you like
done

2) 한 번에 모든 작업을 수행하려면 expr을 사용하십시오. 이는 깨지기 쉬우며 한 이름이 다른 이름의 하위 문자열인 경우 깨집니다. 이 문제는 해결될 수 있지만, 이 경우 더 나은 도구를 사용하는 것이 좋습니다.

$ ARRAY=(jack john jerry )
$ expr "${ARRAY[*]}" : '.*jack.*'
15  # it's found
$ expr "${ARRAY[*]}" : '.*sue.*'
0   # not found

여기서 jack 또는 sue는 $1 또는 확인하려는 매개변수로 대체됩니다.

관련 정보