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

发布于 2024-07-25 05:08:10 字数 350 浏览 5 评论 0原文

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

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

有没有办法实现此目的? 有没有一行命令可以实现这一点?

谢谢。

I need your help.
Let me tell you what my problem is.
I have a text file as follows:

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

As you can see the file has two columns which consist of directory names and their appropriate sizes.

What i want to do is to sort this file by directory's size in a decreasing order like this:

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

Is there a way to achieve this? Is there a one-liner command for this?

THANK YOU.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

找回味觉 2024-08-01 05:08:10

您需要在排序之前标准化尺寸。 最简单的方法是使用 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 中的施瓦茨变换

You need to normalize the size before sorting. The easiest way to do this would be to use a programming language like Perl or Python, but you have already stated that is not an option (although I find it odd that Perl isn't already on the machine). You can use shell code to normalize that data, but it is a pain in the tuckus:

#!/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

This shell script accepts a filename as an argument and prints out the a normalized size, the directory name, and the size. This makes it easy to sort. To get the original fields back, you can just cut off the first field:

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

For those paying attention, yes, I did just write a Schwartzian Transform in shell.

能否归途做我良人 2024-08-01 05:08:10

检查排序手册页。

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

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

Check the sort man page.

To sort the file below on the third field (area code):
Jim Alchin 212121 Seattle
Bill Gates 404404 Seattle
Steve Jobs 246810 Nevada
Scott Neally 212277 Los Angeles
$ sort -k 3,3 people.txt> sorted.txt

Sort in descending (reverse) numeric order:
$ sort -nr

一笑百媚生 2024-08-01 05:08:10
sort -n -r -k 2,2 file.txt

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

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

The -k 2,2 means use the second field in the file as the sort field. By default sort uses whitespace to separate fields. This may not work if the suffixes on the fields (G in your example for gigabytes) are different.

同尘 2024-08-01 05:08:10

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

正如 Drakosha 所指出的,如何对 'du -h' 进行排序按大小输出很好地涵盖了这些问题。

Fundamentally, you have to dehumanize the numbers, sort on the dehumanized numbers, and then remove the dehumanized numbers from the output. While you probably can do it in one line (especially if you write a script to do it for you), I think it will need several lines to be comprehensible.

As noted by Drakosha, How Can I Sort 'du -h' output by size covers the issues quite nicely.

顾铮苏瑾 2024-08-01 05:08:10

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

Using 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

Here, filename is a file that contains the above data. The above one-liner takes care of units G, M and K.

Another shorter implementation using 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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文