Shell 使用sort按列的大小对列进行排序

Shell 使用sort按列的大小对列进行排序,shell,directory,sorting,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 有没有办法做到这一点?这有一个命令行吗 谢谢。检查分拣手册页 要在下面的第三个字段(区号)

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

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
有没有办法做到这一点?这有一个命令行吗


谢谢。

检查分拣手册页

要在下面的第三个字段(区号)上对文件进行排序:
吉姆·阿尔钦212121西雅图
比尔·盖茨404西雅图
史蒂夫·乔布斯246810内华达州
斯科特·尼利212277洛杉矶
$sort-k 3,3 people.txt>sorted.txt

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

使用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

-k2,2表示使用文件中的第二个字段作为排序字段。默认情况下,排序使用空格分隔字段。如果字段上的后缀(在您的示例中,G表示GB)不同,这可能不起作用。

在排序之前,您需要规范化大小。要做到这一点,最简单的方法是使用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中写了一个。基本上,您必须对数字进行非人性化,对非人性化的数字进行排序,然后从输出中删除非人性化的数字。虽然你可能只需要一行就可以完成(特别是如果你写了一个脚本来为你完成),但我认为需要几行才能理解


正如Drakosha所指出的,它很好地解决了这些问题。

字段上的井后缀不同:(我还没有写完整的列表这个问题有多种解决方案:但是我必须更改文本文件的内容..一个只包含一个4kib文件的目录的输出是什么?一个包含10.6kib?的文件..并且您不需要更改文件内容。您可以在内存或临时文件中执行此操作。您是什么类型的系统使用?更严重的是,脚本没有将M作为后缀处理。@Jonathan Leffler:原始帖子是在我发布了一行之后编辑的。无论如何,谢谢你让我知道。@Alan:很公平-更改问题是个问题。
sort -n -r -k 2,2 file.txt
#!/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
./mk_sortable.sh file_to_sort | sort -nr | cut -f2- -d" "