次のことを知りたいです。
非稼働例
> ids=(1 2 3 4);echo ${ids[*]// /|}
1 2 3 4
> ids=(1 2 3 4);echo ${${ids[*]}// /|}
-bash: ${${ids[*]}// /|}: bad substitution
> ids=(1 2 3 4);echo ${"${ids[*]}"// /|}
-bash: ${"${ids[*]}"// /|}: bad substitution
実施例
> ids=(1 2 3 4);id="${ids[@]}";echo ${id// /|}
1|2|3|4
> ids=(1 2 3 4); lst=$( IFS='|'; echo "${ids[*]}" ); echo $lst
1|2|3|4
コンテキストでは、さらに解析するために sed コマンドで使用される区切り文字列。
# REVISION: 2017-03-14
# Use of read and other bash specific features (bashisms)
括弧はstring:ではなくarrayを区切るために使用されるため
ids="1 2 3 4";echo ${ids// /|}
1|2|3|4
いくつかのサンプル:$ids
に2つの文字列を追加:a b
およびc d
ids=("a b" "c d")
echo ${ids[*]// /|}
a|b c|d
IFS='|';echo "${ids[*]}";IFS=$' \t\n'
a b|c d
... そして最後に:
IFS='|';echo "${ids[*]// /|}";IFS=$' \t\n'
a|b|c|d
$IFS
の最初の文字で区切られているが、配列の各要素でスペースが|
で置き換えられた、配列がアセンブルされる場所。
行うとき:
id="${ids[@]}"
arrayids
をスペースでマージした文字列ビルドをstring型の新しい変数に転送します。
注:"${ids[@]}"
がspace-separated文字列を与えると、"${ids[*]}"
(アットマーク*
の代わりに星印@
が付きます) $IFS
の最初の文字で区切られた文字列をレンダリングします。
man bash
の内容:
man -Len -Pcol\ -b bash | sed -ne '/^ *IFS /{N;N;p;q}'
IFS The Internal Field Separator that is used for Word splitting
after expansion and to split lines into words with the read
builtin command. The default value is ``<space><tab><newline>''.
$IFS
で遊ぶ:
set | grep ^IFS= IFS=$' \t\n'
declare -p IFS
declare -- IFS="
"
printf "%q\n" "$IFS"
$' \t\n'
文字通り、space
、tabulation
、および(意味or)line-feed
。したがって、最初の文字はスペースです。 *
を使用すると、@
と同じことが行われます。
しかし:
{
# OIFS="$IFS" # IFS=$': \t\n' # unset array # declare -a array=($(echo root:x:0:0:root:/root:/bin/bash))
IFS=: read -a array < <(echo root:x:0:0:root:/root:/bin/bash)
echo 1 "${array[@]}"
echo 2 "${array[*]}"
OIFS="$IFS" IFS=:
echo 3 "${array[@]}"
echo 4 "${array[*]}"
IFS="$OIFS"
}
1 root x 0 0 root /root /bin/bash
2 root x 0 0 root /root /bin/bash
3 root x 0 0 root /root /bin/bash
4 root:x:0:0:root:/root:/bin/bash
注:行IFS=: read -a array < <(...)
は、:
を永続的に設定せずに、$IFS
をセパレータとして使用します。これは、出力行#2
がスペースを区切り文字として提示するためです。
あなたの最初の質問は F。ハウリの答え で既に述べられています。配列の要素を結合する標準的な方法は次のとおりです。
ids=( 1 2 3 4 )
IFS=\| eval 'lst="${ids[*]}"'
eval
は悪であると大声で叫ぶ人もいますが、ここでは一重引用符のおかげで完全に安全です。これには利点があります。サブシェルはありません。IFS
はグローバルに変更されず、末尾の改行は削除されず、非常に簡単です。
外部コマンドやIFSを操作する必要なく、printf
も使用できます。
ids=(1 2 3 4) # create array
printf -v ids_d '|%s' "${ids[@]}" # yields "|1|2|3|4"
ids_d=${ids_d:1} # remove the leading '|'
引数配列を区切り文字列で分割するユーティリティ関数:
# Split arguments on delimiter
# @Params
# $1: The delimiter string
# $@: The arguments to delimit
# @Output
# >&1: The arguments separated by the delimiter string
split() {
(($#<2)) && return 1 # At least 2 arguments required
local -- delim="$1" str
shift
printf -v str "%s$delim" "$@"
echo "${str:0:-${#delim}}"
}
my_array=( 'Paris' 'Berlin' 'London' 'Brussel' 'Madrid' 'Oslo' )
split ', ' "${my_array[@]}"
出力:
Paris, Berlin, London, Brussel, Madrid, Oslo