23

オプションの引数の長いリストを含むスクリプトがあります。一部には値が関連付けられています。

そのような:

.script --first 2012-12-25 --last 2012-12-26 --copy --remove
.script --first 2012-12-25 

したがって、次のcaseステートメント:

for arg in "$@"
do
    case $arg in
        "--first" )
           START_DATE=$arg;;
        "--last" )
           END_DATE=$arg;;
        "--copy" )
           COPY=true;;
        "--remove" )
           REMOVE=true;;

# ... and so on
   esac
done

私の問題:

次の引数を取得するには、インクリメント$arg+1タイプのステートメントが必要です(場合によっては)。

そんなことがあるものか?

私もそのような部分文字列をやって幸せです.script --first2012-12-25 --last2012-12-26

そこに進む方法がわかりません。

4

5 に答える 5

27

もう少し作業を行うことで、-a=argまたは-aargオプションの両方を許可できます。

START_DATE="$(date '+%Y-%m-%d')";
LAST_DATE="$(date '+%Y-%m-%d')";
while [[ $# -gt 0 ]] && [[ "$1" == "--"* ]] ;
do
    opt="$1";
    shift;              #expose next argument
    case "$opt" in
        "--" ) break 2;;
        "--first" )
           START_DATE="$1"; shift;;
        "--first="* )     # alternate format: --first=date
           START_DATE="${opt#*=}";;
        "--last" )
           LAST_DATE="$1"; shift;;
        "--last="* )
           LAST_DATE="${opt#*=}";;
        "--copy" )
           COPY=true;;
        "--remove" )
           REMOVE=true;;
        "--optional" )
           OPTIONAL="$optional_default";;     #set to some default value
        "--optional=*" )
           OPTIONAL="${opt#*=}";;             #take argument
        *) echo >&2 "Invalid option: $@"; exit 1;;
   esac
done

--optional引数は、「=」が使用されていない場合はデフォルト値を使用し、それ以外の場合は通常の方法で値を設定することに注意してください。

于 2012-12-28T01:36:39.877 に答える
2

各ステートメントshiftの最後に使用します。case

bashマニュアルからの引用:

シフト[n]

n +1...からの位置パラメータは$1...に名前が変更されます。$#から$#-n+1までの数字で表されるパラメータは設定されていません。nは、$#以下の非負数でなければなりません。nが0の場合、パラメーターは変更されません。nが指定されていない場合は、1と見なされます。nが$#より大きい場合、位置パラメーターは変更されません。nが$#より大きいかゼロより小さい場合、戻りステータスはゼロより大きいです。それ以外の場合は0。

于 2012-12-28T00:02:15.613 に答える
2

$@は配列であり、単純な変数ではありません。

としてローカル変数にキャプチャしx=("$@")、インデックスとして配列xを使用できます0 to ($# - 1)

個々の要素にアクセスするには、を使用します${x[$i]}。ただし、直接使用することはできません${@[$i]}

したがって、ループの代わりに、for arg in "$@"ループがありi=0; while [ $i -lt $# ]; doます。

于 2012-12-28T06:31:44.693 に答える
1

複数のオプションがある場合、特に値のあるオプションと値のないオプションが混在している場合は、getoptsに任せてください。

于 2012-12-28T02:26:00.940 に答える
1

getoptsはオプションの引数を持つことができないようです。そうでなければ素晴らしい。

私の解決策

をループし$@、変数を設定しx=$arg て、(argではなく)その変数のケーススイッチを実行します

タイプの引数に対しては正常に機能しました--startdate 2012-12-25 --enddate 2012-12-29

しかし、--removeそれは次の議論がないために機能しませんでした。

したがって、arg文字列に(引数ではない)ものを追加します。

以下を残す

argc="$@ jabberwhocky" 
echo $argc
x=0
# x=0 for unset variable
for arg in $argc
do
   case $x in
        "--start" )
          STARTDATE=$arg ;;
        "--end" )
          ENDDATE=$arg ;;
        "--copy" )
          COPY=true;;
        "--remove" )
          REMOVE=true;;

... 等々....

    esac
    x=$arg
done
于 2012-12-30T00:24:41.293 に答える