配列をダンプするための簡単な1行のトリック
スペースを含む1つの値を追加しました。
foo=()
foo[12]="bar"
foo[42]="foo bar baz"
foo[35]="baz"
私、すぐに捨てる バッシュ使用する配列または連想配列
この1行のコマンド:
paste <(printf "%s\n" "${!foo[@]}") <(printf "%s\n" "${foo[@]}")
レンダリングします:
12 bar
35 baz
42 foo bar baz
説明しました
printf "%s\n" "${!foo[@]}"
改行で区切られたすべてのキーを印刷します
printf "%s\n" "${foo[@]}"
改行で区切られたすべての値を出力します
paste <(cmd1) <(cmd2)
出力合併するcmd1
とcmd2
行ずつ。
見事な
これは-d
スイッチで調整できます:
paste -d : <(printf "%s\n" "${!foo[@]}") <(printf "%s\n" "${foo[@]}")
12:bar
35:baz
42:foo bar baz
あるいは:
paste -d = <(printf "foo[%s]\n" "${!foo[@]}") <(printf "'%s'\n" "${foo[@]}")
foo[12]='bar'
foo[35]='baz'
foo[42]='foo bar baz'
連想配列は同じように機能します。
declare -A bar=([foo]=snoopy [bar]=nice [baz]=cool [foo bar]='Hello world!')
paste -d = <(printf "bar[%s]\n" "${!bar[@]}") <(printf '"%s"\n' "${bar[@]}")
bar[foo bar]="Hello world!"
bar[foo]="snoopy"
bar[bar]="nice"
bar[baz]="cool"
問題改行や特殊文字
残念ながら、これが機能しなくなる少なくとも1つの条件があります。変数に改行が含まれている場合:
foo[17]=$'There is one\nnewline'
コマンドpaste
は行ごとにマージするため、出力は間違ったものになります。
paste -d = <(printf "foo[%s]\n" "${!foo[@]}") <(printf "'%s'\n" "${foo[@]}")
foo[12]='bar'
foo[17]='There is one
foo[35]=newline'
foo[42]='baz'
='foo bar baz'
この作業で%q
は%s
、2番目のprintf
コマンド(およびwhipe quoting)の代わりに使用できます。
paste -d = <(printf "foo[%s]\n" "${!foo[@]}") <(printf "%q\n" "${foo[@]}")
完璧にレンダリングされます:
foo[12]=bar
foo[17]=$'There is one\nnewline'
foo[35]=baz
foo[42]=foo\ bar\ baz
からman bash
:
%q causes printf to output the corresponding argument in a
format that can be reused as shell input.
(a b c)
て、配列に変換します。