POSIX 정규식은 문자열의 첫 번째 발생과 일치합니다.

POSIX 정규식은 문자열의 첫 번째 발생과 일치합니다.

긴 옵션("--option")만 지원하려는 bash 스크립트가 있습니다. --option에는 선택적으로 하나 이상의 인수가 포함됩니다. 첫 번째 "--" 또는 명령줄 문자열의 끝을 제외한 모든 단어(공백으로 구분된 모든 단어)는 "--option-arguments"로 간주됩니다. 결과의 후행 공백은 괜찮습니다. 가능한 모든 옵션은 다른 함수에 의해 호출되므로 최대 성능이 필요합니다. 따라서 bash 루프와 외부 명령을 피하십시오.

"처음 발생" 문제를 발견할 때까지 몇 시간 동안 씨름했습니다.이 답변이것은 POSIX(및 bash)가 탐욕스럽지 않고 게으른 정규식 연산자를 지원하지 않는다는 것을 상기시켜줍니다.

무엇을 해야 할까요?

답변1

옵션은 문자열로 전달되지 않고 다음과 같이 전달되므로 정규식을 사용하여 원하는 방식으로 옵션을 구문 분석할 수 없습니다.목록끈. , , , 및 별도의 인수가 myscript --option foo bar -- qux있으며 공백이 포함되어 있지 않습니다.myscript--optionfoobar--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"

관련 정보