我有一个未从0索引的数组:
arr=([2]=aaa bbb ccc ddd)
Run Code Online (Sandbox Code Playgroud)
我需要得到数组的第一个索引.有很多事情我尝试过并且有效:
for index in "${!arr[@]}"; do
first_index=$index
break
done
Run Code Online (Sandbox Code Playgroud)
first_index=$(awk '{ print $1 }' <<< "${!arr[@]}")
Run Code Online (Sandbox Code Playgroud)
first_index=$(cut -d' ' -f1 <<< "${!arr[@]}")
Run Code Online (Sandbox Code Playgroud)
first_index=${!arr[@]}
first_index=${first_index%% *}
Run Code Online (Sandbox Code Playgroud)
ind=("${!arr[@]}")
first_index=${ind[@]:0:1}
Run Code Online (Sandbox Code Playgroud)
我真正想要的是:
${!arr[@]:0:1}
Run Code Online (Sandbox Code Playgroud)
鉴于此语法对数组运行良好,${arr[@]:0:1}非常干净:
${!arr[@]:0:1}什么?我的尝试似乎使如此简单的任务变得过于复杂
该任务可能看起来很简单,但可能不是常见的用例,因此没有语法糖可以使它变得简单,特别是如果您可以使用其他内置功能来完成它。
你有很多选择,这里还有一个:
put_first_index_in () {
printf -v "${1?}" "%s" "${2?}"
}
put_first_index_in first_index "${!arr[@]}"
Run Code Online (Sandbox Code Playgroud)
${!arr[@]:0:1} 中实际发生了什么?
如果parameter的第一个字符是感叹号(
!),并且parameter不是nameref,则它引入了一层变量间接寻址。Bash 使用由参数的其余部分形成的变量的值作为变量的名称;然后扩展该变量,并在其余替换中使用该值,而不是参数本身的值。这被称为indirect expansion。
作为!第一个字符,支持三种可能的情况:(${!parameter}上面给出的间接扩展)、, ${!prefix*}(${!prefix@}扩展为与 匹配的变量名称prefix)和${!name[*]}, ${!name[@]}(扩展为数组的索引name)。
文档建议仅${!parameter}支持进一步替换,因为仅为此提及而不是其他。因此 bash 尝试执行以下操作:
arr[@]0:1从间接扩展得到的字符串中获取子字符串由于不是标识符中的有效字符,因此我们收到该错误:
$ foo=SHELL
$ echo ${!foo}
/bin/zsh
$ echo ${!foo:0:1}
/
$ foo="SHELL "
$ echo ${!foo}
bash: SHELL : bad substitution
$ arr=([2]=SHELL bbb ccc ddd)
$ echo ${!arr[@]:0:1}
bash: SHELL bbb ccc ddd: bad substitution
Run Code Online (Sandbox Code Playgroud)
因此,这仅适用于单个元素的数组,例如:
$ arr=([2]=SHELL)
Run Code Online (Sandbox Code Playgroud)
正如预期的那样:
$ echo ${!arr[@]:0:1}
/
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
221 次 |
| 最近记录: |