Arrays 将Bash数组转换为分隔字符串
我想知道以下几点:Arrays 将Bash数组转换为分隔字符串,arrays,string,bash,delimited-text,Arrays,String,Bash,Delimited Text,我想知道以下几点: 为什么给定的非工作示例不起作用 除了工作示例中给出的方法外,是否还有其他更干净的方法 非工作示例 工作示例 在上下文中,命令中用于进一步分析的分隔字符串 # REVISION: 2017-03-14 # Use of read and other bash specific features (bashisms) 因为括号用于分隔数组,而不是字符串: ids="1 2 3 4";echo ${ids// /|} 1|2|3|4 一些示例:使用两个字符串填充$id:ab和c
# REVISION: 2017-03-14
# Use of read and other bash specific features (bashisms)
因为括号用于分隔数组,而不是字符串:
ids="1 2 3 4";echo ${ids// /|}
1|2|3|4
一些示例:使用两个字符串填充$id
:ab
和cd
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[@]}"
通过空格将数组ids
的合并生成的字符串转换为字符串类型的新变量
注意:当“${ids[@]}”
给出一个空格分隔的字符串时,“${ids[*]}”
(用星号*
代替at符号@
)将呈现一个由$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=:read-a array<您的第一个问题已在中解决。下面是连接数组元素的标准方法:
ids=( 1 2 3 4 )
IFS=\| eval 'lst="${ids[*]}"'
有些人会大声喊出,eval
是邪恶的,但由于单引号,它在这里是完全安全的。这样做的唯一好处是:没有子shell,IFS
没有全局修改,它不会修剪尾随的换行符,而且非常简单。您也可以使用printf
,无需任何外部命令或操作IFS:
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 '|'
将参数数组连接到分隔字符串的实用函数:
#/usr/bin/env bash
#用分隔符连接参数
#@Params
#$1:分隔符字符串
#${@:2}:要联接的参数
#@输出
#>&1:由分隔符字符串分隔的参数
数组::join(){
(($)| |返回1 |至少需要分隔符
本地--delim=“$1”str IFS=
转移
str=“${*/#/$delim}”#使用前缀分隔符展开参数(空IFS)
echo“${str:${delim}}”#没有第一个分隔符的echo
}
declare-a my_数组=(“巴黎”“柏林”“伦敦”“布鲁塞尔”“马德里”“奥斯陆”)
数组::连接“,”${my_数组[@]}”
数组::联接'*'{1..9}|bc|1*2*3*4*5*6*7*8*9=362880阶乘9
declare-a null_数组=()
数组::join'==零的最终分隔符='“${null_数组[@]}”
输出:
Paris, Berlin, London, Brussel, Madrid, Oslo
362880
${${ids[*]}//}
是一个语法错误,仅此而已。不知道您试图在这里实现什么。试图在1跳中实现变量替换,它永远不会起作用…相关:。因此,这是一个typeof和变量替换错误${需要字符串类型的变量,但没有收到。感谢您的详细解释。您也可以跳过字符串赋值,仍然可以使用printf'%smyDelim'${array[@]}将数组转换为带有任意分隔符的分隔字符串,而不必是单个字符
。可以通过管道将分隔符myDelim
的最后一个实例导入到sed-e的/myDelim$/'
,但这很麻烦。更好的主意?@JonathanY。如果是这样,请使用printf-v myVar'%smyDelim'${array[@]};myVar=“${myVar%myDelim”
而不是fork tosed
,除非它不会跳过变量赋值,例如,当使用printf
为另一个可执行文件提供输入参数时。我知道赋值一个变量可能更快、更便宜;只是感觉不那么优雅。@F.Hauri在myDelim周围必须有双引号。你还必须有$symbol.Lite这个“%s$myDelim”这对我来说是最简单的,因为我在数组元素之间有>1个字符串,而且在我的情况下,我也不需要删除“多余的”。工作起来很愉快!printf-v strng“'%s',\n”${thearray[*]}
:)同意,使用最简单。此外,如果您使用带有语法突出显示的IDE,这也是一个用户友好的选项,不会像中那样拾取eval
'd语法。非常方便,谢谢!也许join
会是一个更合适的名称,不过,与join
函数的工作方式一致?@theudeabides无法直接命名它join
,因为这与连接文件行的现有命令名冲突。*facepalm*-啊,是的,当然。我忘了。
{
# 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
ids=( 1 2 3 4 )
IFS=\| eval 'lst="${ids[*]}"'
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 '|'
Paris, Berlin, London, Brussel, Madrid, Oslo
362880