【问题标题】:How to sort string array in descending order in Bash?如何在 Bash 中按降序对字符串数组进行排序?
【发布时间】:2017-03-04 17:42:10
【问题描述】:

假设我有一个数组:

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

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

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

非常感谢您的帮助!

【问题讨论】:

  • 尝试sort -r 颠倒顺序。
  • 它有效!非常感谢!
  • 也可以写arr=($(printf '%s\n' "${nameArr[@]}" | sort -r))
  • 我会说没关系,因为复杂性应该是一样的。我说的对吗?
  • printf '%s\n' ${arr[@]} 只是一个很好的提醒,它会一个接一个地处理输入字符串中的所有值,替换 for 循环(在这种情况下),相同的功能。 (想想使用printf 一次处理两个单词是多么容易)。您也可以认为最短的代码获胜;-)。祝你好运。

标签: arrays bash shell sorting scripting


【解决方案1】:

您可以使用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

使用/输出示例

调用脚本会产生以下结果:

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

注意: 完成排序后不要忘记恢复默认 IFS=$' \t\n'spacetabnewline)脚本继续。

【讨论】:

    【解决方案2】:

    您的问题启发了我创建一个我相信将来会派上用场的功能:

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

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

    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,")

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

    这个函数也适用于整数数组:

    $ 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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-01-09
      • 2020-09-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多