使用Linux/Bash对空格分隔的数字进行排序

25

有没有可以用来对以空格为分隔符的数字字符串进行排序的Linux工具或Bash命令?


非常相关 - user202729
9个回答

42

这里有一个简单的例子可以让你开始学习:

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

tr 命令将数字之间的空格转换成换行符,因为 sort 命令使用换行符作为分隔符(也就是用来排序文本)。-g 参数告诉 sort 命令按照“通用数字值”进行排序。

请参考 man sort 以获取关于 sort 命令的更多信息。


5
我添加了另一个| tr,并反转了参数,以便将空格分隔的字符串输出。 - blee
要反转排序,请使用-r - Tim
将结果输出为带有空格的形式:echo \echo "81 4 6 12 3 0" | tr " " "\n" | sort -g | tr "\n" " "`` - baz

14

这是对 @JamesMorris 答案的一种变化:

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

我使用xargs -n1而不是tr来进行新行转换。最后的xargs命令是将数字转换回以空格分隔的序列。


这非常方便,但为什么 xargs -n1xargs 要那样做呢? - Jacktose
默认情况下(如果未指定实用程序),xargs 使用 echo 处理输入,其余内容只涉及如何处理参数:-n1 表示每次调用最多一个。 - FranMowinckel

4
这是对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

3
$ s=(one two three four)
$ sorted=$(printf "%s\n" ${s[@]}|sort)
$ echo $sorted
four one three two

$ sorted=$(printf "%s\n" ${s[@]}|sort) 定义了一个排序后的值数组sorted。 - Pau Coma Ramirez

1

使用 Bash 参数扩展(将空格替换为换行符),我们可以执行以下操作:

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

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

1
我将以下代码添加到我的.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和其他人的启发。

0
如果你实际上有一个以空格分隔的数字字符串,那么其他答案提供的方法都可以正常工作。如果你的列表是一个bash数组,则:
oldIFS="$IFS"
IFS=$'\n'
array=($(sort -g <<< "${array[*]}"))
IFS="$oldIFS"

可能有更好的解决方案。如果您想将其推广到对字符串数组进行排序,换行符分隔符会很有帮助。


我的列表是一个Bash数组,但这对我不起作用:packages="$(sort <<< ${!package2apk[@]})" - Jayen

0
$ awk 'BEGIN{split(ARGV[1], numbers);for(i in numbers) {print numbers[i]} }' \
     "6 7 4 1 2 3" | sort -n

虽然这段代码片段可能是解决方案,但包括解释真的有助于提高您的帖子质量。请记住,您正在回答未来读者的问题,而这些人可能不知道您的代码建议的原因。 - yivi

0
通过将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}"

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接