如何对人类可读的大小进行排序

如何对人类可读的大小进行排序

我基本上是在寻找文件,然后按大小排序。如果我不按人类可读的大小对大小进行排序,该脚本就可以工作。但我希望尺寸是人类可读的。如何对人类可读的尺寸进行排序?

例如:

 ls -l | sort -k 5 -n | awk '{print $9 " " $5}'

这按预期工作,我的文件大小以字节升序排列:

1.txt 1
test.txt 3
bash.sh* 573
DocGeneration.txt 1131
andres_stuff.txt 1465
Branches.xlsx 15087
foo 23735
bar 60566
2016_stuff.pdf 996850

现在,我希望大小是人类可读的,所以我向 ls 添加了一个 -h 参数,现在有些文件乱序了:

 ls -lh | sort -k 5 -n | awk '{print $9 " " $5}'
1.txt 1
DocGeneration.txt 1.2K
andres_stuff.txt 1.5K
test.txt 3
Branches.xlsx 15K
foo 24K
bar 60K
bash.sh* 573
2016_stuff.pdf 974K

答案1

尝试sort -h k2

-h, -- human-numeric-sort 比较人类可读的数字(例如,2K 1G)

它是 gnu 排序、BSD 排序等的一部分。

答案2

ls内置此功能,使用该-S选项并按相反顺序排序:ls -lShr

       -r, --reverse
              reverse order while sorting

       -S     sort by file size, largest first

答案3

由于没有提到特定的 shell,因此以下是如何在zshshell 中完成整个操作:

ls -lhf **/*(.Lk-1024oL)

glob模式与路径名中的**like *but across相匹配/,即像递归搜索一样。

ls命令将使用 启用人类可读的大小-h,并使用 启用长列表输出格式-l。该-f选项禁用排序,因此ls只会按照给定的顺序列出文件。

此顺序按文件名通配模式排列,**/*(.Lk-1024oL)以便首先列出较小的文件。该**/*位匹配此目录及以下目录中的每个文件和目录,但会(...)修改 glob 的行为(它是“glob 限定符”)。

oL最后的 ( ) 按文件大小( “长度”)o对名称进行排序。L

开头的.使 glob 仅匹配常规文件(无目录)。

Lk-1024位选择大小小于 1024 KB 的文件(“以 KB 为单位的长度小于 1024”)。

如果zsh不是您的主要交互式 shell,那么您可以使用

zsh -c 'ls -lf **/*(.Lk-1024oL)'

使用setopt GLOB_DOTS(或zsh -o GLOB_DOTS -c ...) 也可以匹配隐藏名称。 ...或者只是添加D到 glob 限定符字符串中。


扩展上面的内容,假设您想要一个带有路径名和人类可读大小的 2 列输出,并且还假设您有numfmt来自 GNU coreutils 的输出,

zmodload -F zsh/stat b:zstat

for pathname in **/*(.Lk-1024oL); do
    printf '%s\t%s\n' "$pathname" "$(zstat +size "$pathname" | numfmt --to=iec)"
done

或者,更快,

paste <( printf '%s\n' **/*(.Lk-1024oL) ) \
      <( zstat -N +size **/*(.Lk-1024oL) | numfmt --to=iec )

答案4

这行得通吗?

ls -l | awk '{if ($5<=1024) {print}}' | sort -k 5 -n | awk '{print $9"\t"substr($5/1024,1,3)"k"} '| column -t

第一个awkexp 将查找小于 1M 的文件,第二个 exp 将从结果中获取字节大小并将其转换为 KB 并打印前 3 个元素以给出人类可读的大小。

相关内容