使用sort按列大小排列列

时间:2009-06-28 12:29:53

标签: shell directory sorting

我需要你的帮助。 让我告诉你我的问题是什么。 我有一个文本文件如下:

Music 3.6G
Other 254.5M
Videos 4.6G
Games 1.3G
Apps 10.1G

正如您所看到的,该文件有两列,其中包含目录名称及其相应的大小。

我想要做的是按目录的大小按照下列顺序对此文件进行排序:

Apps 10.1G
Videos 4.6G
Music 3.6G
Games 1.3G
Other 254.5M

有没有办法实现这个目标?这是否有一个单行命令?

谢谢。

5 个答案:

答案 0 :(得分:1)

您需要在排序前规范化大小。最简单的方法是使用像Perl或Python这样的编程语言,但是你已经说过这不是一个选项(尽管我发现Perl还没有出现在机器上很奇怪)。你可以使用shell代码来规范化那些数据,但这很麻烦:

#!/bin/bash

ECHO=/bin/echo
TR=/usr/bin/tr
BC=/usr/bin/bc

while read dir size; do
    bytes=`$ECHO $size | $TR -d "[A-Z]"`
    case $size in
        *B) bytes=$bytes                                      ;;
        *K) bytes=`$ECHO "$bytes * 1024" | $BC`               ;;
        *M) bytes=`$ECHO "$bytes * 1024 * 1024" | $BC`        ;;
        *G) bytes=`$ECHO "$bytes * 1024 * 1024 * 1024" | $BC` ;;
        *) $ECHO unknown size type                            ;;
    esac
    echo $bytes $dir $size
done < $1

此shell脚本接受文件名作为参数,并打印出规范化大小,目录名称和大小。这使得排序变得容易。要恢复原始字段,您可以切断第一个字段:

./mk_sortable.sh file_to_sort | sort -nr | cut -f2- -d" "

对于那些关注的人,是的,我只是在shell中写了Schwartzian Transform

答案 1 :(得分:0)

检查排序手册页。

要在第三个字段(区号)上对下面的文件进行排序:
Jim Alchin 212121西雅图
比尔盖茨404404西雅图
史蒂夫乔布斯246810内华达州 Scott Neally 212277洛杉矶
$ sort -k 3,3 people.txt&gt; sorted.txt

按降序(反向)数字顺序排序:
$ sort -nr

答案 2 :(得分:0)

使用Perl:

perl -nle'$G{$2}=$1 if/(\w+) (\d+\.?\d*)G/;$M{$2}=$1 if/(\w+) (\d+\.?\d*)M/;$K{$2}=$1 if/(\w+) (\d+\.?\d*)K/;END{print"$G{$_} ${_}G"for sort{$b<=>$a}keys%G;print"$M{$_} ${_}M"for sort{$b<=>$a}keys%M;print"$K{$_} ${_}K"for sort{$b<=>$a}keys%K;}' filename

此处,filename是包含上述数据的文件。以上单行内容负责单位GMK

使用eval的另一个较短的实现:

perl -nle'/(\w+) (\d+\.?\d*)(\w)/;eval"\$\$3{$2} = $1";END{for$u qw(G M K){eval"print\"\$\$u{$_} $_$u\""for sort{$b<=>$a}keys%{$u}}}' filename

答案 3 :(得分:0)

sort -n -r -k 2,2 file.txt

-k 2,2表示使用文件中的第二个字段作为排序字段。默认情况下,sort使用空格来分隔字段。如果字段上的后缀(示例中的G为千兆字节)不同,则可能无效。

答案 4 :(得分:0)

从根本上说,你必须对数字进行去人性化,对非人化数字进行排序,然后从输出中删除非人化数字。虽然你可能可以在一行中完成(特别是如果你编写一个脚本来为你做),我认为它需要几行才能理解。

如Drakosha所述,How Can I Sort 'du -h' output by size非常清楚地涵盖了这些问题。