我在Bash中有一个数组,例如:
array=(a c b f 3 5) 我需要对数组进行排序。不仅以排序的方式显示内容,还可以使用排序的元素来获取新数组。新排序的数组可以是全新的数组,也可以是旧的数组。
问题来源于stack overflow
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。
您实际上并不需要那么多代码:
IFS=$'\n' sorted=($(sort <<<"${array[*]}")) unset IFS 在元素中支持空格(只要它不是换行符),并在Bash 3.x中工作。
例如:
$ array=("a c" b f "3 5") $ IFS=$'\n' sorted=($(sort <<<"${array[*]}")); unset IFS $ printf "[%s]\n" "${sorted[@]}" [3 5] [a c] [b] [f] 注: @sorontar已经指出,如果元素包含通配符,如需要小心*或?:
sorted =($(...))部分正在使用“ split and glob”运算符。您应该关闭glob:set -f或set -o noglob或shopt -op noglob或数组中的一个元素,如*将会扩展到文件列表。
发生了什么: 结果是按此顺序发生了六件事:
IFS=$'\n' "${array[*]}" <<< sort sorted=($(...)) unset IFS 首先, IFS=$'\n' 这是我们操作的重要组成部分,它通过以下方式影响2和5的结果:
鉴于:
"${array[*]}" 扩展到以的第一个字符分隔的每个元素 IFS sorted=() 通过拆分的每个字符来创建元素 IFS IFS=$'\n' 进行设置,以便使用新行作为分隔符扩展元素,然后以每行成为元素的方式创建元素。(即在新行上拆分。)
用新行定界很重要,因为这就是sort操作方式(按行排序)。仅用换行分隔不是很重要,但是需要保留包含空格或制表符的元素。
的默认值IFS是space,tab,后跟换行,并且不适合我们的操作。
接下来的sort <<<"${array[*]}"部分 <<<,在这里称为字符串,接受的扩展"${array[*]}",如上所述,并将其输入到的标准输入中sort。
在我们的示例中,sort以下字符串被馈入:
a c b f 3 5 由于sort sort,它产生:
3 5 a c b f 接下来的sorted=($(...))部分 该$(...)部分称为命令替换,使它的内容(sort <<<"${array[*]})作为普通命令运行,同时将所得的 标准输出作为原位置$(...)。
在我们的示例中,这类似于简单地编写:
sorted=(3 5 a c b f ) sorted 然后成为通过在每个新行上拆分此文字而创建的数组。
最后, unset IFS 这会将的值重置为IFS默认值,这只是一个好习惯。
这是为了确保我们不会IFS对脚本中后面依赖的任何内容造成麻烦。(否则,我们需要记住,我们已经改变了一切,这对于复杂的脚本来说可能是不切实际的。)