はじめに
shellscriptで配列の末尾に、右方向への代入を用いて要素を追加する方法を述べる。
環境
PC: MacBookPro (2016)
bash: GNU bash, バージョン 5.2.26(1)
zsh: 5.8.1 (x86_64-apple-darwin21.0)
準備(zshの場合)
zshでは配列の先頭の配列番号は1である(0ではなく!)。それでは都合が悪いので、setopt ksharrays
で配列番号が0から始まるようにする。
また、コードの一部がglob表現として認識されてしまうのか、「no matches found」というエラーが出るため、それを回避するためにsetopt nonomatch
とする。
コード(zshの場合)
以下のようにすれば、右方向代入で、配列末尾に要素を追加できる。
#!/bin/zsh
# 準備
setopt nonomatch
setopt ksharrays
#配列を準備
arr=(1 2)
#3をarrの末尾に加える
echo '3' | read -d '' arr[${#arr[@]}]
#全要素を確認
echo ${arr[@]} #結果: 1 2 3
#要素数を確認
echo ${#arr[@]} #結果: 3
準備(bash)の場合
bashの場合はzshと異なり、配列番号は0から始まるので、zshの時のような操作は不要。
ただし、bashはzshと異なり、最後のパイプもサブプロセスとなるため、そのサブプロセス内の変数をカレントプロセスから取り出せない。bashでもzshと同様の動作をさせるためにshopt -s lastpipe
を用いる。
また、現在のmacのデフォルトシェルはzshであるためか、macのデフォルト(/bin/bash)のbashはバージョン「GNU bash, version 3.2.57」と古いバージョンである。上記の「lastpipe」機能はBash 4.2以降らしいので(ChatGPTより)、ここでエラーが出る。であるため、brew install bash
で新しいバージョンをインストールしておく。インストールした新しいbashのパスは/usr/local/bin/bashであった。
コード(bash)
#!/usr/local/bin/bash
# 準備
shopt -s lastpipe
# 配列を準備
arr=(1 2)
# 3をarrの末尾に加える
echo '3' | read -d '' arr[${#arr[@]}]
# 全要素を確認
echo ${arr[@]}
# 要素数を確認
echo ${#arr[@]}