如何在 Bash 中按降序对字符串数组进行排序?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/40193122/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 15:20:27  来源:igfitidea点击:

How to sort string array in descending order in Bash?

arraysbashshellsortingscripting

提问by prone666

let's say I have an array:

假设我有一个数组:

nameArr=("Leia", "Darth Vader", "Anakin", "Han Solo", "Yoda")

nameArr=("Leia", "Darth Vader", "Anakin", "Han Solo", "Yoda")

and I would like to sort in descending order. How could I do it in Bash shell scripting? In ascending order I am using command:

我想按降序排序。我怎么能在 Bash shell 脚本中做到这一点?按升序我使用命令:

arrAsc=($(for l in ${nameArr[@]}; do echo $l; done | sort))

arrAsc=($(for l in ${nameArr[@]}; do echo $l; done | sort))

Thanks a lot for help!

非常感谢您的帮助!

采纳答案by David C. Rankin

You can do so fairly easily making use of IFS(internal field separator), sort -r, and a little help from printf. Using command substitutionyou can output and sort the array and then simply read the sorted results back into nameArr. For instance:

您可以相当轻松地利用IFS(内部字段分隔符) sort -r、 和printf. 使用命令替换,您可以输出和排序数组,然后只需将排序结果读回nameArr. 例如:

#!/bin/bash

nameArr=("Leia", "Darth Vader", "Anakin", "Han Solo", "Yoda")

IFS=$'\n'           ## only word-split on '\n'
nameArr=( $(printf "%s\n" ${nameArr[@]} | sort -r ) )  ## reverse sort

declare -p nameArr  ## simply output the array

Example Use/Output

示例使用/输出

Calling the script results in the following:

调用脚本的结果如下:

$ bash revarr.sh
declare -a nameArr='([0]="Yoda" [1]="Leia," [2]="Han Solo," [3]="Darth Vader," [4]="Anakin,")'

note:don't forget to restore the default IFS=$' \t\n'(space, tab, newline) when done with the sort if your script continues.

注意:如果您的脚本继续,请不要忘记在排序完成后恢复默认值IFS=$' \t\n'(space,tab,newline)。

回答by Jeffrey Cash

Your question inspired me to whip up a function that I'm sure will come in handy in the future:

你的问题激励我创建一个我相信将来会派上用场的函数:

sort_array () { local v="$1[*]" IFS=$'\n'; read -d $'\0' -a "$1" < <(sort "${@:2}" <<< "${!v}"); }

sort_array () { local v="$1[*]" IFS=$'\n'; read -d $'\0' -a "$1" < <(sort "${@:2}" <<< "${!v}"); }

Usage: sort_array NameOfArrayVariable [flags to pass to sort command]

用法:sort_array NameOfArrayVariable [传递给排序命令的标志]

With nameArr=("Leia", "Darth Vader", "Anakin", "Han Solo", "Yoda"):
calling sort_array nameArrwill result in nameArr containing ("Anakin," "Darth Vader," "Han Solo," "Leia," "Yoda"); calling sort_array nameArr -rwill result in nameArr containing ("Yoda" "Leia," "Han Solo," "Darth Vader," "Anakin,")

With nameArr=("Leia", "Darth Vader", "Anakin", "Han Solo", "Yoda"):
调用sort_array nameArr将导致 nameArr 包含 ("Anakin"、"Darth Vader"、"Han Solo"、"Leia"、"Yoda");调用sort_array nameArr -r将导致 nameArr 包含(“Yoda”、“Leia”、“Han Solo”、“Darth Vader”、“Anakin”)

Also, just a heads up, when you declare or set an array in bash, you do not comma separate elements, as "Leia",is the same as "Leia,"unless you set IFS to contain a comma.

另外,请注意,当您在 bash 中声明或设置数组时,不要用逗号分隔元素,除非您将 IFS 设置为包含逗号"Leia","Leia,"否则相同。

This function also works well with integer arrays:

此函数也适用于整数数组:

$ nums=()
$ for ((i=0; i<10; ++i)); do nums+=($RANDOM); done
$ echo "${nums[@]}";
22928 7011 18865 24027 18559 9037 3885 10873 32369 21932
$ sort_array nums -n
$ echo "${nums[@]}"
3885 7011 9037 10873 18559 18865 21932 22928 24027 32369
$ sort_array nums -nr 
$ echo "${nums[@]}"
32369 24027 22928 21932 18865 18559 10873 9037 7011 3885