0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

bash - associative array(連想配列)

Last updated at Posted at 2023-11-15

bash array

bash では、他のプログラミング言語と同様に array(配列)を使用することが出来ます。ここでは、RHEL8 を例に取り、代表的な associative array(連想配列)の操作方法をご紹介します。

$ cat /etc/redhat-release
Red Hat Enterprise Linux release 8.8 (Ootpa)

$ bash --version
GNU bash, version 4.4.20(1)-release (x86_64-redhat-linux-gnu)
Copyright (C) 2016 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>

This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Create & Manipulate associative array

以下のような方法で associative array を作成することが出来ます。

$ declare -A ASSO_A=([a]="aaa" [b b]="bbb" [c@+c]="ccc")
$ declare -p ASSO_A
declare -A ASSO_A=([c@+c]="ccc" [a]="aaa" ["b b"]="bbb" )

代表的な配列要素(element)の操作には、以下があります。

# Number of elements
$ echo ${#ASSO_A[@]}
3

# Index List
$ echo "${!ASSO_A[@]}"
c@+c a b b

$ for I in "${!ASSO_A[@]}"; do echo "$I : ${ASSO_A[$I]}"; done
c@+c : ccc
a : aaa
b b : bbb

# Get All Elements
$ echo ${ASSO_A[@]}
ccc aaa bbb
$ echo ${ASSO_A[*]}
ccc aaa bbb

# Get Specific Elements
$ echo ${ASSO_A[c@+c]}
ccc
$ echo ${ASSO_A[b b]}
bbb

Slice 操作ではエラーが発生しませんが、期待した結果にならない場合があります。

# Get Elements with Slice #1
$ echo ${ASSO_A[@]:-1}
ccc aaa bbb
$ echo ${ASSO_A[@]:0}
ccc aaa bbb
$ echo ${ASSO_A[@]:1}
ccc aaa bbb
$ echo ${ASSO_A[@]:2}
aaa bbb
$ echo ${ASSO_A[@]:3}
bbb
$ echo ${ASSO_A[@]:4}


# Get Elements with Slice #2
$ echo ${ASSO_A[@]:-1:1}
ccc aaa bbb
$ echo ${ASSO_A[@]:0:1}
ccc
$ echo ${ASSO_A[@]:1:1}
ccc
$ echo ${ASSO_A[@]:2:1}
aaa
$ echo ${ASSO_A[@]:3:1}
bbb
$ echo ${ASSO_A[@]:4:1}

Element の追加・削除等も可能です。

# Add Elements
$ ASSO_A[z zz z]="Additional Element"
$ declare -p ASSO_A
declare -A ASSO_A=(["z zz z"]="Additional Element" [c@+c]="ccc" [a]="aaa" ["b b"]="bbb" )
$ echo ${!ASSO_A[@]}
z zz z c@+c a b b

# Delete Elements
$ unset ASSO_A["b b"]
$ declare -p ASSO_A
declare -A ASSO_A=(["z zz z"]="Additional Element" [c@+c]="ccc" [a]="aaa" )
$ echo ${!ASSO_A[@]}
z zz z c@+c a

ファイルからの入力でも associative array を作成することが出来ます。以下のファイルを使用してみます。

$ cat associative_input.txt
[A]="aa"
[B B]="bb"
[C Cc C]="cc"
[D-.@]="dd"
$ declare -A ASSO_B
$ eval ASSO_B=( $(cat associative_input.txt) )
$ declare -p ASSO_B
declare -A ASSO_B=([D-.@]="dd" ["C Cc C"]="cc" [A]="aa" ["B B"]="bb" )

$ for I in "${!ASSO_B[@]}"; do echo "$I : ${ASSO_B[$I]}"; done
D-.@ : dd
C Cc C : cc
A : aa
B B : bb

コマンド出力からでも associative array を作成することが出来ます。以下のコマンドを使用してみます。

$ systemctl list-timers
NEXT                         LEFT          LAST                         PASSED       UNIT                         ACTIVATES
Tue 2023-11-14 21:10:00 JST  6min left     Tue 2023-11-14 21:00:17 JST  2min 56s ago sysstat-collect.timer        sysstat-collect.service
Wed 2023-11-15 00:00:00 JST  2h 56min left Tue 2023-11-14 09:05:39 JST  11h ago      mlocate-updatedb.timer       mlocate-updatedb.service
Wed 2023-11-15 00:00:00 JST  2h 56min left Tue 2023-11-14 09:05:39 JST  11h ago      unbound-anchor.timer         unbound-anchor.service
Wed 2023-11-15 00:07:00 JST  3h 3min left  n/a                          n/a          sysstat-summary.timer        sysstat-summary.service
Wed 2023-11-15 18:01:58 JST  20h left      Tue 2023-11-14 18:01:58 JST  3h 1min ago  systemd-tmpfiles-clean.timer systemd-tmpfiles-clean.service

5 timers listed.
Pass --all to see loaded but inactive timers, too.

Timer Unit (UNIT) を Key に、次回時刻 (NEXT) を Value にして作成してみます。
associative array 用に awk で文字列を加工します。

$ systemctl --no-legend list-timers | awk '{print "["$(NF-1)"]=\""$1,$2,$3,$4"\""}'
[sysstat-collect.timer]="Tue 2023-11-14 21:10:00 JST"
[mlocate-updatedb.timer]="Wed 2023-11-15 00:00:00 JST"
[unbound-anchor.timer]="Wed 2023-11-15 00:00:00 JST"
[sysstat-summary.timer]="Wed 2023-11-15 00:07:00 JST"
[systemd-tmpfiles-clean.timer]="Wed 2023-11-15 18:01:58 JST"

上記を元に associative array を作成することができます。

$ declare -A ASSO_C
$ eval ASSO_C=( $(systemctl --no-legend list-timers | awk '{print "["$(NF-1)"]=\""$1,$2,$3,$4"\""}') )
$ declare -p ASSO_C
declare -A ASSO_C=([systemd-tmpfiles-clean.timer]="Wed 2023-11-15 18:01:58 JST" [unbound-anchor.timer]="Wed 2023-11-15 00:00:00 JST" [mlocate-updatedb.timer]="Wed 2023-11-15 00:00:00 JST" [sysstat-collect.timer]="Tue 2023-11-14 21:10:00 JST" [sysstat-summary.timer]="Wed 2023-11-15 00:07:00 JST" )

$ for I in "${!ASSO_C[@]}"; do echo "$I : ${ASSO_C[$I]}"; done
systemd-tmpfiles-clean.timer : Wed 2023-11-15 18:01:58 JST
unbound-anchor.timer : Wed 2023-11-15 00:00:00 JST
mlocate-updatedb.timer : Wed 2023-11-15 00:00:00 JST
sysstat-collect.timer : Tue 2023-11-14 21:10:00 JST
sysstat-summary.timer : Wed 2023-11-15 00:07:00 JST
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?