bashで配列の最後の要素を読み取る方法はありますか?


68

たとえば、5つの要素を持つ配列がある場合:

[a][b][c][d][e]

使用してecho ${myarray[4]}、それが何を保持しているかを見ることができます。

しかし、与えられた配列の要素の数がわからない場合はどうでしょうか?未知の長さの配列の最後の要素を読み取る方法はありますか?すなわち、任意の配列の右から左に読み取る最初の要素?

これをbashで行う方法を知りたいです。


$@配列ではありません(添字を付けることはできません)。それについては、シェルスクリプトに渡される最後の引数の取得を参照してください。
トム・ヘイル

回答:


89

あなただけのことができ、負のインデックスを使用する ${myarray[-1]}最後の要素を取得します。2番目から最後まで同じことを行うことができます。Bashの場合:

インデックス付き配列の要素を参照するために使用される添え字がゼロ未満の数値に評価される場合、配列の最大インデックスよりも大きいものと比較して解釈されるため、負のインデックスは配列の最後からカウントされ、 -1のインデックスは最後の要素を参照します。

同じことが割り当てにも有効です。「式」と言うとき、それは本当に式を意味します。配列の長さを${#myarray[@]}明示的に使用して計算するものを含め、そこに任意の算術式を記述してインデックスを計算できます。


2
あなたにはそれを行うことができますkshし、zsh同様に。
ジャニス

5
zshいえ、デフォルトのアレイによって1インデックスとは異なりますbashし、kshどこに0から始まるインデックスです。
スティーブンキット

2
はい、もちろん; この質問に対する短い答えは変わりませんが、長い形式が言及されているので、そこでの動作の違いを指摘する必要があると思いました。
スティーブンキット

22
負のインデックスは、bash 4.3以降でのみ機能します。
-cuonglm

10
少なくともv10.11.5の時点でMac OS Xに含まれているBashのバージョンは3.2のみであるため、Macでは機能しません。
ドクターJ

45

モダンバッシュ(v4.1以降)

indexの最後の要素を読むことができます-1

$ a=(a b c d e f)
$ echo ${a[-1]}
f

bashバージョン4.1-alphaで開始された負のインデックスを使用して、数値インデックス配列に最後からアクセスするためのサポート。

古いbash(v4.0以前)

配列の長さ${#a[@]}を取得し、1を減算して最後の要素を取得する必要があります。

$ echo ${a[${#a[@]}-1]}
f

bashは配列の添え字を算術式として扱うため$((...))、算術評価を強制するためになどの追加の表記法は必要ありません。


最後の1つは私には機能しません。私はBash v4.1.2(1)を使用しています。最後のアイテムを印刷する代わりに、配列全体を印刷するだけです。
アレクセイマグラ

ただし、@ cuonglmの答えは機能します。
アレクセイマグラ

modernバージョンで資格を得ることができれば、答えはさらに良くなります。
サンビーン

1
正確にアンサーを完璧にするために必要なもの。
サンビーン

1
これありがとう。echo $ {a [$(($ {#a [@]}-1]))}を使用していました。「bashは配列の添え字を算術式として扱う」ことを知らなかったからです。
ブルーノブロノスキー

15

bash配列の割り当て、参照、負のインデックスによる設定解除は、bash 4.3でのみ追加されました。の古いバージョンではbash、インデックスで式を使用できますarray[${#array[@]-1}]

別の方法として、古いバージョンbash(bash 3.0以上)でも動作します:

$ a=([a] [b] [c] [d] [e])
$ printf %s\\n "${a[@]:(-1)}"
[e]

または:

$ printf %s\\n "${a[@]: -1}"
[e]

負のオフセット使用して、分離する必要がある:-と混同されないように:-拡張。


1
それを作成する"${a[@]: -1}"と、で(bashおよびzsh)でも動作しkshます。
ジャニス

Kornshellドキュメント(www2.research.att.com/sw/download/man/man1/ksh.html)で完全に指定されています。(のドキュメント検査なかったのzshかをbash、私はすべての3つのシェルでそれをテストした。)
ジャニス・

@Janis:bashのドキュメントを読み直し、これについても言及しました。再度、感謝します。
cuonglm

4

アレイ

bash(bash 3.0以降)で最も古い選択肢は次のとおりです。

$ a=(aa bb cc dd ee)
$ echo "${a[@]:(-1)}   ${a[@]: -1}   ${a[@]:(~0)}   ${a[@]:~0}"
ee   ee   ee   ee

(デフォルト値を使用)の展開として:マイナスが続くという解釈を避けるためにスペースが必要です。-"${var:-abc}"

~算術あるビットごとの否定(1の補数と同等またはすべてのビットを反転します)。man bashから:

算術評価

      ! ~         logical and bitwise negation  

bash-4.2 +以降:

$ echo "${a[-1]}   ${a[(~0)]}"
ee   ee

bash 5.0以降も:

$ echo "${a[~0]}"
ee

すべてのbashバージョン(古いbash)の場合:

$ echo "${a[   ${#a[@]}-1   ]}"    # spaces added **only** for readability
ee

@

位置引数の場合(bash 2.01以降):

$ set aa bb cc dd ee
$ echo "${@:(-1)} ${@:~0} ${@: -1} ${@:$#}   ${!#}"
ee ee ee   ee

すべてのシェルのポータブルソリューションは、evalを使用することです。

eval printf '"%s\n"' \"\${$#}\"

bash 5+構文のリファレンスはありますか?マニュアル~で58個すべてのインスタンスを検索しましたが表示されませんでした。
トム・ヘイル

...そしてどのようにそれを行うの$@ですか?bash: ${@[@]:(-1)}: bad substitution
トム・ヘイル

1
はい、man bash参照があります(@タイトルの展開された回答を確認してください)。@TomHale
アイザック

1
@ない配列(まあ、ない完全に配列 bashで)、それは、インデックス(受け入れない[]個々の引数のための)添字を。使用する${@:(-1)}か、同等のものが必要です。@タイトルの拡張エントリを確認します。@TomHale
アイザック

-2

また、これを行うことができます:

$ a=(a b c d e f)
$ echo ${a[$(expr ${#a[@]} - 1)]}

結果:

$ f

あなたがしているのは、0の配列インデックスからではなく、すべての要素を取得しているため、配列内の要素のすべての数を取得し、-1を減算することです

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.