
스크립트의 셸 매개변수에 특정 매개변수 "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
. 인수는 변수에 포함됩니다.-fjava8
found
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
. 테스트가 다음과 같은 경우진짜, 이 두 매개변수를 건너뛰어야 하므로 카운터가 skip
2로 설정됩니다. 또한 found
다른 인스턴스를 찾았음을 나타내기 위해 증가합니다 -f java8
.
첫 번째 위치 인수가 이면 -fjava8
이 단일 인수를 건너뛰어야 하므로 카운터가 skip
1로 설정됩니다. 또한 found
다른 인스턴스를 찾았음을 나타내기 위해 증가합니다 -fjava8
( find 와 동일 -f java8
).
이 명령문 이후에는 case
카운터를 감소시키고 0이 아닌 경우 첫 번째 위치 인수를 닫는 것 외에는 아무것도 수행하지 않습니다. 0인 경우 호출하기 전에 첫 번째 위치 인수를 목록 끝으로 이동하여 유지하는 인수가 목록을 통해 루프백되도록 효과적으로 허용하고 필요하지 않은 인수는 제거합니다.skip
shift
skip
skip
shift
루프에서 위치 인수 목록을 사용하고 있으므로 마지막 인수가 이고 -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