AWK 命令通过使用 ls -l 查找文件以 mb、kb 或 gb 为单位打印大小

AWK Command print size in mb,kb or gb by finding a file using ls -l

我想使用 find 命令获取文件大小以及以 kb、mb 或 gb 为单位的大小,小数点后两位。

期望的输出:

15.04 MB
10MB
10GB

我尝试了以下命令但出现错误:

find /orabackup/EXPDP/ATRUS001 -name "expdp_ATRUS001_04122017_0500.dmp" -exec ls -ltr  {} \;  | awk ' {s+=}' '{ split( "B KB MB GB TB PB" , v ); s=1; while( >1024 ){ /=1024; s++ } printf "%.2f %s", , v[s] }'

输出:

awk: cmd. line:1: fatal: cannot open file `{ split( "B KB MB GB TB PB" , v ); s=1; while( >1024 ){ /=1024; s++ } printf "%.2f %s", , v[s] }' for reading (No such file or directory

即使文件存在于目录中,但仍出现上述错误。谢谢你的帮助。

awk ' {s+=}' '{ split( "B... ?

为什么要将 awk 程序分成 两个 参数?这几乎肯定是导致您出现问题的原因。

它将第一个参数视为 awk 程序,将第二个参数视为输入文件。您的错误消息支持这一点,指出 "cannot open file '{ split ..."。您需要做的是将 awk 程序作为 单个 参数提供。


顺便说一句(虽然我不确定 Solaris),许多 GNU 实用程序都支持 -h 选项来生成人类可读的大小。你试过 ls -h 了吗?

根据 Oracle docs,Solaris 支持这一点,尽管它可能无法提供您想要的两位小数。


另外,如果您对单个大小感兴趣,我无法理解您为什么要尝试将每一行的文件大小 添加 s。我也不明白为什么你使用 </code> 进行划分,而这将是 <code>ls 输出的 drwxr-xr-x 部分。

也许您最好更详细地指定您想要实现的目标。

我现在能做的最好的就是提供这个作为例子:

pax> find . -name '[a-z]*' -exec ls -ltr {} ';' | awk 'BEGIN{split("B KB MB GB TB PB EB ZB YB",v)} {s=1;while(>1024&&s<9){/=1024;s++}printf "%6.2f %-2s %s\n",,v[s],}'
154.00 B  ./etc_ntp.conf
150.00 B  ./input.txt
  1.85 KB ./qq.sh
200.00 B  ./tmp00

这似乎基本上就是您要尝试做的事情,尽管您需要针对您的具体情况修改 find 参数(我只是抓取了所有以小写字母开头的文件)。

它还限制了 s,这样如果您有 EB 大小的文件,您就不会 运行 离开数组的末尾:-)

为了便于阅读而对其进行分解:

BEGIN {
    # Only need do this once, allow for bigger files.
    split("B KB MB GB TB PB EB ZB YB", v)
}
{
    # Select B suffix.
    s=1

    # Need higher suffix, but stop at YB.
    while ( > 1024 && s < 9)
    {
        # Divide by 1K, go to next suffix.
         /= 1024
        s++
    }

    # Pretty-print the line.
    printf "%6.2f %-2s %s\n", , v[s], 
}

简短优化find + numfmt 解决方案:

find /your_dirpath -type f -name "filepath" -printf "%s\n" | numfmt --to=iec --format='%.2fB'
  • -printf "%s\n" - 打印文件大小
  • numfmt ... - 转换数字from/to人类可读的字符串

示例输出:

3.70MB
24.27MB
38.16MB
1.76MB