すべての要素を繰り返さずに配列全体([key] = value)を印刷する方法はありますか?
いくつかの要素を含む配列を作成するとします。
declare -A array
array=([a1]=1 [a2]=2 ... [b1]=bbb ... [f500]=abcdef)
配列全体を再印刷できます。
for i in "${!array[@]}"
do
echo "${i}=${array[$i]}"
done
${!array[@]}
しかし、Bashはすべての配列要素(キーと値)を一度に取得する方法をすでに知っているようです${array[@]}
。
繰り返しないでbashにこの情報を印刷させる方法はありますか?
編集:
typeset -p array
これをやってください!
ただし、一度にプレフィックスとサフィックスの両方を削除することはできません。
a="$(typeset -p array)"
b="${a##*(}"
c="${b%% )*}"
出力のkey = value部分のみを取得または印刷するためのよりきれいな方法はありますか?
ベストアンサー1
私はあなたがそこに2つの異なることを求めていると思います。
繰り返しないでbashにこの情報を印刷させる方法はありますか?
はい、しかしループを使うのと同じくらい良くありません。
出力のkey = value部分のみを取得または印刷するためのよりきれいな方法はありますか?
うん、for
ループです。利点は、外部プログラムが不要でシンプルでパニックにならず、正確な出力形式を簡単に制御できることです。
declare -p
()の出力を処理する解決策は、typeset -p
a)変数自体にかっこまたは大括弧が含まれる可能性、およびb)その出力がシェルへのdeclare -p
有効な入力になるように追加する必要がある引用符を処理する必要があります。
たとえば、b="${a##*(}"
キー/値に開かれる角かっこが含まれている場合、拡張時に値の一部が消費されます。使用##
して削除したからです。最長プレフィックス。についても同様ですc="${b%% )*}"
。印刷されたテンプレートをより正確に一致させることはできますが、declare
参照しているものすべてを望まない場合は、まだ困難に直面します。
必ず必要な場合でなければ良くないようです。
$ declare -A array=([abc]="'foobar'" [def]='"foo bar"')
$ declare -p array
declare -A array='([def]="\"foo bar\"" [abc]="'\''foobar'\''" )'
ループを使用すると、for
必要に応じて出力形式を選択する方が簡単です。
# without quoting
$ for x in "${!array[@]}"; do printf "[%s]=%s\n" "$x" "${array[$x]}" ; done
[def]="foo bar"
[abc]='foobar'
# with quoting
$ for x in "${!array[@]}"; do printf "[%q]=%q\n" "$x" "${array[$x]}" ; done
[def]=\"foo\ bar\"
[abc]=\'foobar\'
そこでもシンプルそれ以外の場合は、出力形式を変更します(キーの周りの括弧を削除し、すべてのキーと値のペアを1行に入力します...)。シェル自体以外のものを参照する必要がある場合でも、直接参照する必要がありますが、少なくとも作業する生データが必要です。 (キーまたは値に改行がある場合は、いくつかの引用が必要になる場合があります。)
printf "[%s]=%s" "${x@Q}" "${array[$x]@Q}"
現在Bash(私の考えでは4.4)ではprintf "%q=%q"
。 (配列の極端なケースとして引用していますが、キーではありません。)@
%q
forループが書くのに疲れすぎるようであれば、関数として保存してください(ここでは引用しません)。
printarr() { declare -n __p="$1"; for k in "${!__p[@]}"; do printf "%s=%s\n" "$k" "${__p[$k]}" ; done ; }
その後、使用してください。
$ declare -A a=([a]=123 [b]="foo bar" [c]="(blah)")
$ printarr a
a=123
b=foo bar
c=(blah)
インデックス配列にも機能します。
$ b=(abba acdc)
$ printarr b
0=abba
1=acdc