【问题标题】:Sorting space delimited numbers with Linux/Bash使用 Linux/Bash 对空格分隔的数字进行排序
【发布时间】:2011-02-07 05:34:45
【问题描述】:

我可以使用 Linux 实用程序或 Bash 命令对以空格分隔的数字字符串进行排序吗?

【问题讨论】:

标签: linux bash


【解决方案1】:

这里有一个简单的例子来帮助你:

echo "81 4 6 12 3 0" | tr " " "\n" | sort -g

tr 将分隔数字的空格转换为回车,因为 sort 使用回车作为分隔符(即它用于对文本的 进行排序)。 -g 选项告诉 sort 按“一般数值”排序。

man sort 了解有关sort 的更多详细信息。

【讨论】:

  • 我附加了另一个| tr,参数颠倒了,以得到一个空格分隔的字符串。
  • 要反转排序,请使用-r
【解决方案2】:
$ s=(one two three four)
$ sorted=$(printf "%s\n" ${s[@]}|sort)
$ echo $sorted
four one three two

【讨论】:

  • $ sorted= ( $(printf "%s\n" ${s[@]}|sort) ) 再次将 sorted 定义为值数组,但已排序
【解决方案3】:

这是 ghostdog74 的 答案的变体,太大而无法放入评论中。它显示的是数字而不是数字的名称,并且原始字符串和结果都是以空格分隔的字符串(而不是成为换行符分隔字符串的数组)。

$ s="3 2 11 15 8"
$ sorted=$(echo $(printf "%s\n" $s | sort -n))
$ echo $sorted
2 3 8 11 15
$ echo "$sorted"
2 3 8 11 15

如果您在设置sorted 的值时没有使用echo,则字符串中有换行符。在这种情况下,不带引号回显它会将其全部放在一行上,但是,正如用引号回显它所显示的那样,每个数字将出现在它自己的行上。无论原始是数组还是字符串都是这种情况。

# demo
$ s="3 2 11 15 8"
$ sorted=$(printf "%s\n" $s | sort -n)
$ echo $sorted
2 3 8 11 15
$ echo "$sorted"
2
3
8
11
15

【讨论】:

    【解决方案4】:

    使用 Bash 参数扩展(用换行符替换空格)我们可以这样做:

    str="3 2 11 15 8" 
    sort -n <<< "${str// /$'\n'}"
    
    # alternative
    NL=$'\n'
    str="3 2 11 15 8"
    sort -n <<< "${str// /${NL}}"
    

    【讨论】:

      【解决方案5】:

      如果您实际上有一个以空格分隔的数字字符串,那么提供的其他答案之一可以正常工作。如果你的列表是一个 bash 数组,那么:

      oldIFS="$IFS"
      IFS=$'\n'
      array=($(sort -g <<< "${array[*]}"))
      IFS="$oldIFS"
      

      可能是一个更好的解决方案。如果您想推广到对字符串数组而不是数字进行排序,则换行符会有所帮助。

      【讨论】:

      • 我的列表是一个 bash 数组,但这对我不起作用:packages="$(sort &lt;&lt;&lt; ${!package2apk[@]})"
      【解决方案6】:
      $ awk 'BEGIN{split(ARGV[1], numbers);for(i in numbers) {print numbers[i]} }' \
           "6 7 4 1 2 3" | sort -n
      

      【讨论】:

      • 虽然此代码 sn-p 可能是解决方案,但 including an explanation 确实有助于提高您的帖子质量。请记住,您是在为将来的读者回答问题,而这些人可能不知道您提出代码建议的原因。
      【解决方案7】:

      通过将 IFS 的范围限制为单个命令来改进 Evan Krall 的漂亮 Bash“数组排序”:

      printf "%q\n" "${IFS}"
      array=(3 2 11 15 8) 
      array=($(IFS=$'\n' sort -n <<< "${array[*]}")) 
      echo "${array[@]}" 
      printf "%q\n" "${IFS}"
      

      【讨论】:

        【解决方案8】:

        这是@JamesMorris 答案的变体:

        echo "81 4 6 12 3 0" | xargs -n1 | sort -g | xargs
        

        我使用xargs -n1 而不是tr 来转换为新行。最后的xargs 是转换回一个空格分隔的数字序列。

        【讨论】:

        • 这非常方便,但是为什么xargs -n1xargs 这样做呢?
        • xargs 默认情况下(如果未指定实用程序)在输入上使用echo,其余的只是它如何处理参数:-n1 每次调用最多一个。
        【解决方案9】:

        我将此添加到我的.zshrc(或.bashrc)文件中:

        #sort a space-separated list of words (e.g. a list of HTML classes)
        sortwords() {
          echo $1 | xargs -n1 | sort -g | xargs
        }
        

        像这样从终端调用它:

        sortwords "banana date apple cherry"
        
        # apple banana cherry date
        

        感谢@FranMowinckel 和其他人的启发。

        【讨论】:

          猜你喜欢
          • 2021-03-30
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2023-03-05
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-05-18
          相关资源
          最近更新 更多