(注:この質問の動機は、単にbash
プログラミング知識を向上させるためのものです。)
にbash
対応する表現を知りたいです。zsh
$@[2,$#]
まっすぐ$@
シェル関数(またはスクリプト)のコマンドライン引数の配列()の範囲を指定します。
(アドレス範囲をオンラインで見つけたすべてのソリューション$@
はbash
、間接的な$@
アドレス指定はすべて中間変数に最初に割り当てる必要があるためです。以下の例を参照してください。)
具体的に言えば、bash
次のテスト機能zsh
と同等のものは何ですか?
testfn () {
printf '>%s<\n' $@[2,$#]
}
% testfn a b c d
>b<
>c<
>d<
上記のように、私が思いついた最も近い方法は次のとおりです。$@
中間変数に割り当てる必要があります。
testfn () {
holdargs=( $@ )
printf '>%s<\n' "${holdargs[@]:1}"
}
中間変数を必要としないすべての試行はエラーのため失敗しますbad substitution
。
答え1
これは私にとって効果的です。
testfn () {
printf '>%s<\n' "${@:2}"
}
例:
$ testfn a b c d
>b<
>c<
>d<
$@ Expands to the positional parameters, starting from one. When the expansion occurs within double quotes, each parameter expands to a separate word.
位置パラメータセクションの表示バッシュハッカーウィキしかも広く使われているより多くの例と詳細については、セクションを参照してください。
これは通常二重引用符を使用する場合です$@
。"$@"
それ以外の場合、"${@:2}"
返された結果は二重引用符の結果になります。
$@
配列要素には、次の表記法を使用してアクセスできます。
"${@:START:COUNT}"
「過剰使用」セクションからの抜粋
これにより、STARTから始めてCOUNT個の位置パラメータが展開されます。 COUNTは省略できます(${@:START})、この場合、STARTで始まるすべての場所引数が拡張されます。
要素が空ですか?
他の人は、上記の内容が空の要素を処理できないため、同じではないと指摘しました。私はBash 4.1.7を使っていますが、そうです。
例:
$ testfn "" a "" c d e
>a<
><
>c<
>d<
>e<
$ testfn '' a '*' c d e
>a<
>*<
>c<
>d<
>e<
$ testfn "" a " " c d e
>a<
> <
>c<
>d<
>e<
答え2
存在するzsh
、
printf '<%s>\n' ${@[2,$#]}
それは同じです
printf '<%s>\n' $@[2,-1]
null 以外の位置要素 2 を最後の要素まで印刷します。これは作成と同じです($# == 5の場合)。
printf '<%s>\n' $2 $3 $4 $5
だから:
$ set 1 2 '' '*' 5
$ printf '<%s>\n' $@[2,-1]
<2>
<*>
<5>
同等のものを得るには、bash
次のものが必要です。
$ set 1 2 '' '*' 5
$ a=("$@")
$ IFS=; set -f
$ printf '<%s>\n' ${a[@]:1}
<2>
<*>
<5>
動作しないため、中間配列が必要です${@:2}
(少なくとも4.2.45ではありません)。
もちろん、空であるかどうかにかかわらず、最初の要素を除くすべての要素が必要な場合は、次のように書く必要があります。
$ printf '<%s>\n' "$@[2,-1]"
<2>
<>
<*>
<5>
zsh
一緒にする
$ printf '<%s>\n' "${@:2}"
<2>
<>
<*>
<5>
存在するbash
。
構文はzsh
最後に含まれているので${array:first:n}
(cshスタイルの修飾子と競合しない場合のみ)、上記のbash(実際にはksh)コードは最新のバージョンですzsh
。
${a[@]:1}
との違いがある理由は、orとは逆に配列から位置をコピーするときと同様に、配列がリーンでインデックスが0から始まること${@:2}
を覚えておく必要があります。bash
zsh
csh
rc
ksh
bash
${a[@]:4:5}
インデックスが4以上の最初の5つの要素を返します。最初の要素$@
のインデックスは 1( $1
) で、 で定義された配列a=(...)
の要素は 0 から始まるインデックスに設定されます。
まあ、それは完全に真実ではありません。で like は $# > 0 の場合にのみ while (引用符なし) のように拡張され、bash
設定されていないか空でない場合にのみ可能です。これは私にバグのように聞こえます。では動作は異なりますが、再び一貫しています。"$@"
"$1" "$2" "$3" "$4" "$5"
"${@:0:1}"
"$0"
"$@"
"${@:1}"
$@
${@:1}
$IFS
ksh