开发者社区 问答 正文

如何在Bash中对数组排序

我在Bash中有一个数组,例如:

array=(a c b f 3 5) 我需要对数组进行排序。不仅以排序的方式显示内容,还可以使用排序的元素来获取新数组。新排序的数组可以是全新的数组,也可以是旧的数组。

问题来源于stack overflow

展开
收起
保持可爱mmm 2020-02-07 01:29:47 571 分享 版权
1 条回答
写回答
取消 提交回答
  • 您实际上并不需要那么多代码:

    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对脚本中后面依赖的任何内容造成麻烦。(否则,我们需要记住,我们已经改变了一切,这对于复杂的脚本来说可能是不切实际的。)

    2020-02-07 01:30:01
    赞同 展开评论
问答分类:
问答标签:
问答地址: