POSIX 正規表示式符合字串第一次出現的位置

POSIX 正規表示式符合字串第一次出現的位置

我有 bash 腳本,我只想支援長選項(“--option”)。 --option 可以選擇包含一個或多個參數。直到但不包括第一個“--”或命令列字串末尾的所有單字(任何由空格分隔的內容)都被視為“--option-arguments”。結果中的尾隨空格是可以的。由於每個可能的選項都會被其他函數調用,因此需要最大的效能。因此,盡量避免 bash 循環和外部命令。

與“第一次出現”問題鬥爭了很多小時,直到我發現這個答案這提醒我 POSIX(以及 bash)不支援非貪婪/惰性正規表示式運算子。

怎麼辦?

答案1

您無法按照您想要的方式使用正規表示式解析選項,因為選項不是以字串形式傳遞,而是以清單字串。myscript --option foo bar -- quxmyscript, --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"

相關內容