![POSIX 정규식은 문자열의 첫 번째 발생과 일치합니다.](https://linux55.com/image/83556/POSIX%20%EC%A0%95%EA%B7%9C%EC%8B%9D%EC%9D%80%20%EB%AC%B8%EC%9E%90%EC%97%B4%EC%9D%98%20%EC%B2%AB%20%EB%B2%88%EC%A7%B8%20%EB%B0%9C%EC%83%9D%EA%B3%BC%20%EC%9D%BC%EC%B9%98%ED%95%A9%EB%8B%88%EB%8B%A4..png)
긴 옵션("--option")만 지원하려는 bash 스크립트가 있습니다. --option에는 선택적으로 하나 이상의 인수가 포함됩니다. 첫 번째 "--" 또는 명령줄 문자열의 끝을 제외한 모든 단어(공백으로 구분된 모든 단어)는 "--option-arguments"로 간주됩니다. 결과의 후행 공백은 괜찮습니다. 가능한 모든 옵션은 다른 함수에 의해 호출되므로 최대 성능이 필요합니다. 따라서 bash 루프와 외부 명령을 피하십시오.
"처음 발생" 문제를 발견할 때까지 몇 시간 동안 씨름했습니다.이 답변이것은 POSIX(및 bash)가 탐욕스럽지 않고 게으른 정규식 연산자를 지원하지 않는다는 것을 상기시켜줍니다.
무엇을 해야 할까요?
답변1
옵션은 문자열로 전달되지 않고 다음과 같이 전달되므로 정규식을 사용하여 원하는 방식으로 옵션을 구문 분석할 수 없습니다.목록끈. , , , 및 별도의 인수가 myscript --option foo bar -- qux
있으며 공백이 포함되어 있지 않습니다.myscript
--option
foo
bar
--
qux
루프는 bash의 메소드입니다.
case "$1" in
--option1)
shift
while [[ $# -ne 0 && "$1" != "--" ]]; do
option1_args+=("$1")
shift
done
(($# == 0)) || shift
done
성능이 큰 문제라면 bash를 사용하면 안 됩니다. ksh를 사용해 보세요. 무료이며 거의 모든 곳에서 사용할 수 있습니다. 기본적으로 설치되어 있지 않더라도 일반적으로 bash보다 훨씬 빠릅니다. 그래도 너무 느리다면 Perl, Python 또는 Ruby와 같은 더 높은 수준의 프로그래밍 언어가 필요합니다.
답변2
이 다소 간단한 해결책을 찾았습니다 ...
function optionArg () {
local _find="$1"; shift 1
local _optarg=""
local _reBeg=""
#
_reBeg="${_find}"'[= ]+(.*?)( --)?'
### no regex nongreedy operator support in POSIX
### will have to just truncate after first match
#
if [[ "$*" =~ $_reBeg ]]
then
_optarg="${BASH_REMATCH[1]}"
### all arguments following --option[= ]
#
_optarg="${_optarg%%--*}"
### limit to just arguments up to next --option (no lazy support in POSIX)
#
return 0
else
return 1
fi
옵션이 포함된 스크립트 또는 함수 호출이 주어지고 그 뒤에 다음과 같은 다른 옵션이 따라옵니다.
otherfunction --option1 arg1 arg2 --option2 -- file1 /home/me/file2
otherfunction()이 허용하는 각 옵션에 대해 optionArg()가 다음과 같이 호출됩니다.
_optarg1="$(optionArg --option1 "$@")"
_optarg2="$(optionArg --option2 "$@")"
_optarg3="$(optionArg -- "$@")"
결과는 다음과 같습니다...
_optarg1="arg1 arg2 "
_optarg2=""
_optarg3="file1 /home/me/file2"