如何解决如何在 Bash 中对数组进行排序
你真的不需要那么多代码:
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指出,如果元素包含通配符,例如*
or,则需要小心?
:
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
是 一个空格 , 一个制表符 ,后跟 一个新行 ,不适合我们的操作。
接下来是sort <<<"${array[*]}"
部分
<<<
,这里称为 strings"${array[*]}"
,如上所述,接受 的扩展,并将其馈送到 的标准输入中sort
。
在我们的示例中,sort
输入以下字符串:
a c
b
f
3 5
由于sort
sorts ,它产生:
3 5
a c
b
f
接下来是sorted=($(...))
部分
该$(...)
部分称为 命令替换
,导致其内容 ( sort <<<"${array[*]}
) 像普通命令一样运行,同时将生成的 标准输出 作为原文本$(...)
。
在我们的示例中,这会产生类似于简单编写的内容:
sorted=(3 5
a c
b
f
)
sorted
然后成为一个数组,通过在每一行上拆分这个文字来创建。
最后,unset IFS
这会将 的值重置为IFS
默认值,这是一种很好的做法。
这是为了确保我们不会对IFS
脚本后面依赖的任何内容造成麻烦。(否则我们需要记住我们已经改变了一些东西——这对于复杂的脚本来说可能是不切实际的。)
解决方法
我在 Bash 中有一个数组,例如:
array=(a c b f 3 5)
我需要对数组进行排序。不仅以排序的方式显示内容,还可以获得一个包含排序元素的新数组。新排序的数组可以是全新的或旧的。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。