쉘 인수에서 특정 인수의 존재 및 제거를 식별합니다.

쉘 인수에서 특정 인수의 존재 및 제거를 식별합니다.

스크립트의 셸 매개변수에 특정 매개변수 "java8"이 있는지 확인하고 있는 경우 이를 제거해야 합니다. 또한 다른 변수에 저장하고 싶지만 $*에서는 제거하고 싶습니다.

arg가 존재하는지 확인하기 위해 getopts를 사용해 보았지만 인수를 제거하는 방법을 모르겠습니다.

참고 - "java8" 위치에 대한 인수 확인을 알 수 없습니다. 어디에나 있을 수 있습니다.

while getopts "f:" flag
do
     case $flag in
         f)
           echo $OPTARG
           ;;
     esac
done
echo $*
~

그래서 기본적으로 내가 전화할 때 -

./test.sh arg1 arg2 -f java8 arg3

getopts 블록을 실행한 후 나머지 매개변수는 다음과 같습니다.

매개변수 1, 매개변수 2, 매개변수 3

답변1

POSIX 셸(임시 배열을 사용하지 않음)의 경우: 제거된 옵션의 수를 계산하는 동안 위치 인수 목록 -f뒤에 있거나 위치 인수 목록에서 모든 인스턴스를 제거합니다 java8. 인수는 변수에 포함됩니다.-fjava8found

skip=0 found=0
for arg do
    case $1 in
        -f)
            if [ "$2" = java8 ]; then
                skip=2
                found=$(( found + 1 ))
            fi
            ;;
        -f*)
            if [ "$1" = -fjava8 ]; then
                skip=1
                found=$(( found + 1 ))
            fi
    esac

    if [ "$skip" -eq 0 ]; then
        set -- "$@" "$1"
    else
        skip=$(( skip - 1 ))
    fi
    shift
done

if [ "$skip" -eq 1 ]; then
    set -- "$@" -f
    found=$(( found - 1 ))
fi

printf 'Args: %s\n' "$*"
printf 'Found = %d\n' "$found"

위의 루프에는 위치 매개변수의 초기 수만큼 반복이 있습니다.

첫 번째 위치 인수가 이면 -f두 번째 위치 인수가 인지 테스트합니다 java8. 테스트가 다음과 같은 경우진짜, 이 두 매개변수를 건너뛰어야 하므로 카운터가 skip2로 설정됩니다. 또한 found다른 인스턴스를 찾았음을 나타내기 위해 증가합니다 -f java8.

첫 번째 위치 인수가 이면 -fjava8이 단일 인수를 건너뛰어야 하므로 카운터가 skip1로 설정됩니다. 또한 found다른 인스턴스를 찾았음을 나타내기 위해 증가합니다 -fjava8( find 와 동일 -f java8).

이 명령문 이후에는 case카운터를 감소시키고 0이 아닌 경우 첫 번째 위치 인수를 닫는 것 외에는 아무것도 수행하지 않습니다. 0인 경우 호출하기 전에 첫 번째 위치 인수를 목록 끝으로 이동하여 유지하는 인수가 목록을 통해 루프백되도록 효과적으로 허용하고 필요하지 않은 인수는 제거합니다.skipshiftskipskipshift

루프에서 위치 인수 목록을 사용하고 있으므로 마지막 인수가 이고 -f첫 번째 인수가 이면 마지막 인수가 손실됩니다 java8. 이것이 마지막 if진술이 방지하려는 의도입니다.

답변2

어쩌면 이런 게 있지 않을까요? 삭제하고 싶은 것 같은데 -f java8...

#!/bin/bash

while (( $# )); do
    if [[ $1 = "-f" ]] && [[ $2 = "java8" ]]; then
        shift 2
        continue
    fi

    args+=( "$1" )
    shift
done

echo "${args[*]}"

사용 예:

$ ./argtest.sh one two three
one two three
$ ./argtest.sh one two -f java8 three four
one two three four
$ ./argtest.sh -f java8 -f foo -f bar
-f foo -f bar

관련 정보