将 Bash 数组转换为分隔字符串 [英] Converting a Bash array into a delimited string
问题描述
我想知道以下内容;
- 为什么给定的非工作示例不起作用.
- 是否还有其他比工作示例中给出的方法更简洁的方法.
非工作示例
> 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 中使用的分隔字符串进一步解析的命令.
In context, the delimited string to be used in a sed command for further parsing.
推荐答案
# REVISION: 2017-03-14
# Use of read and other bash specific features (bashisms)
因为括号用于分隔数组,而不是字符串:
Because parentheses are used to delimit an array, not a string:
ids="1 2 3 4";echo ${ids// /|}
1|2|3|4
一些示例:用两个字符串填充 $ids
:a b
和 c d
Some samples: Populating $ids
with two strings: a b
and 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
的第一个字符分隔,但在数组的每个元素中用 |
替换空格.
Where array is assembled, separated by 1st char of $IFS
, but with space replaced by |
in each element of array.
当你这样做时:
id="${ids[@]}"
您将 array ids
通过空格合并后的字符串构建转移到 string 类型的新变量.
you transfer the string build from the merging of the array ids
by a space to a new variable of type string.
注意:当"${ids[@]}"
给出一个空格分隔的字符串时,"${ids[*]}"
(使用星号 *
而不是 at 符号 @
)将呈现由 的 第一个字符分隔的字符串>$IFS
.
Note: when "${ids[@]}"
give a space-separated string, "${ids[*]}"
(with a star *
instead of the at sign @
) will render a string separated by the first character of $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'
字面意思是一个空格
、一个制表
和(意思是或)一个换行
.所以,虽然第一个字符是一个空格.*
的使用与 @
的作用相同.
Literally a space
, a tabulation
and (meaning or) a line-feed
. So, while the first character is a space. the use of *
will do the same as @
.
但是:
{
# 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
将空格作为分隔符.
Note: The line IFS=: read -a array < <(...)
will use :
as separator, without setting $IFS
permanently. This is because output line #2
present spaces as separators.
这篇关于将 Bash 数组转换为分隔字符串的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!