我在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 -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
对脚本中后面依赖的任何内容造成麻烦。(否则,我们需要记住我们已经改变了一些方法,这对于复杂的脚本来说可能是不切实际的。)
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句