Bash 配列を区切り文字でJOINする方法
Bashスクリプトで、配列からさくっとカンマ 区切りで文字列を出力したい場合など、あると思います。 他の言語でもよくある、リスト構造にセパレート文字を指定して結合してるメソッド、join的なものがBashにはないので、どうやってやるのか紹介します。
BashスクリプトでやるJoin処理
先にやり方を書くと、こんな感じになります。 配列変数を展開するのですが、printfに渡して書式指定でカンマ区切りにしています。 さらに変数展開のスライスで余分なカンマを除くようになっています。
arr=(
id
name
age
)
line=$(printf ",%s" "${arr[@]}")
line=${line:1}
echo "$line"
# ==> id,name,age
Bash配列
Bashの配列は ()
で要素を囲って定義します。
要素はスペースで区切られますが、スペースを含む要素の場合はダブルクォーテーションで囲います。
arr=(hoge piyo "foo bar")
要素へのアクセスは添字を使います。
echo "${arr[0]}"
#==> hoge
echo "${arr[1]}"
#==> piyo
echo "${arr[2]}"
#==> foo bar
全要素を展開して出力する場合、@
を使います。
JavaScriptでいうスプリット表現みたいなものです。
echo "${arr[@]}"
#==> hoge piyo foo bar
出力されたものだと、ちょっと見分けつかないですが、
echo “hoge” “piyo” “foo bar”
といった感じで、要素毎にちゃんとクォートされて指定のコマンド引数に渡されているのと同じです。
似た指定として、echo "${arr[*]}"
というのもありますが、
こちらは、echo "hoge piyo foo bar"
と、すべての要素が一つに展開されるイメージです。
Bash変数展開
parameter expansion
${parameter:offset}
${parameter:offset:length}
変数の値をオフセット指定して取得することができます。
x=hello
echo "${x:1}"
#==> ello
echo "${x:2}"
#==> llo
echo "${x:3}"
#==> lo
今回の例で使ってるのはオフセット1を指定することで、 先頭の1文字以降だけを取得することで、最初のカンマ文字を読み飛ばしています。
printfコマンド
printfは、C言語にあるものと似たような動きをするコマンドです。 特徴的なのは、パラメータの数がフォーマットで指定したものより多い場合、出力が繰り返えされるという事です。
printf "%s\n" hoge piyo foo
#==> hoge
#==> piyo
#==> foo
printf "%s-%s\n" hoge piyo foo
#==> hoge-piyo
#==> foo-
これを利用する事で、要素ごとにカンマ文字を付けて出力することができます
まとめ
最終的に冒頭で書いたように、これらの表現を組み合わせて、join処理ができます。 他にもタブや改行でも、同じような対応ができます。 区切りの文字数が増える場合は、スライスのサイズを調整しましょう。
配列をカンマ 区切りにするだけでも、意外とテクニックが必要なBashスクリプトですが、 ひとつずつ挙動を理解して便利に使いましょう。
今回はBashスクリプトを前提に話をしています。 おそらく、Zshとか他のシェルだと特に配列周りの挙動が違ったりするので注意しましょう。