如何在Bash中对数组排序

u32004

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

array=(a c b f 3 5)

我需要对数组进行排序。不仅以排序的方式显示内容,还可以使用排序的元素来获取新数组。新排序的数组可以是全新的数组,也可以是旧的数组。

安塔克

您实际上并不需要那么多代码:

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 -fset -o noglobshopt -op noglob或数组中的一个元素,如*将会扩展到文件列表。

发生了什么:

结果是按此顺序发生了六件事:

  1. IFS=$'\n'
  2. "${array[*]}"
  3. <<<
  4. sort
  5. sorted=($(...))
  6. unset IFS

首先, IFS=$'\n'

这是我们操作的重要组成部分,它通过以下方式影响2和5的结果:

鉴于:

  • "${array[*]}" 扩展到以的第一个​​字符分隔的每个元素 IFS
  • sorted=() 通过拆分的每个字符来创建元素 IFS

IFS=$'\n' 进行设置,以便使用新行作为分隔符扩展元素,然后以每行成为元素的方式创建元素。(即在新行上拆分。)

用新行定界很重要,因为这就是sort操作方式(按行排序)。仅用换行分隔不是很重要,但是需要保留包含空格或制表符的元素。

的默认值IFSspacetab,后跟换行,并且不适合我们的操作。

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

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章