在 awk 中的特定列上应用 numfmt

在 awk 中的特定列上应用 numfmt

我正在编写一个脚本tcsh(是的......我知道但我必须)来分析特定目录中的所有用户磁盘使用情况。

最后,我想生成以下格式的报告:

user1 1.6GB
user2 1.1GB
..
user69 10MB

首先我跑步

find . -printf "%u  %s\n" | awk '{user[$1]+=$2}; END{ for( i in user) print i " " user[i]}' > example.tmp

然后我设法通过以下方式将第二列转换为人类可读的大小:

awk '{ print $2 }' example.tmp | numfmt --to=iec-i --suffix=B --padding=7

但我无法将其合并回上一专栏的位置。有没有办法numfmt直接将命令注入awk求和?

我对“awk”命令有点弱,所以请原谅我的糟糕代码。

答案1

您应该能够通过使用直接将格式限制为仅第二个字段--field的选项来避免这样做,即numfmt

find . -printf "%u  %s\n" | 
  awk '{user[$1]+=$2}; END{ for(i in user) print i, user[i]}' | 
  numfmt --field=2 --to=iec-i --suffix=B --padding=7

如果您确实需要在 awk 中应用numfmton 作为特定值,那么这里有一个适用于简单情况并且不需要的变体getline var

find . -printf "%u  %s\n" | 
  awk '
    {user[$1]+=$2}
    END {
      cmd = "numfmt --to=iec-i --suffix=B --padding=7"; 
      for(i in user){ printf "%s ", i; print user[i] | cmd; close(cmd) } 
    }
  '

答案2

您可以通过numfmt从内部调用命令来实现此目的awk,例如:

awk '{cmd=sprintf("numfmt --to=iec-i --suffix=B --padding=7 %d",$2); cmd | getline converted; close(cmd); print $1,converted}' example.tmp

这样,您也可以在第一次awk调用中直接实现它:

find . -printf "%u  %s\n" | awk '{user[$1]+=$2};
  END{
     for(i in user) {
        cmd=sprintf("numfmt --to=iec-i --suffix=B %d",user[i]);
        cmd | getline converted;
        close(cmd);
        printf("%s % 7s\n",i,converted)
     }
  }'

答案3

测试并运行良好

#!/usr/bin/python
import os
import subprocess
from os import *
users=[]
for i,j,k in os.walk('<directory>'):
    for m in  k:
        fil=str(i)+str(m)
        if os.path.isfile(fil):
            if os.stat(fil).st_uid not in users:
                users.append(os.stat(fil).st_uid)



for u in users:
    size=0
    for i,j,k in os.walk('<Directory>'):
        for z in k:
            fil=str(i)+str(z)
            if os.path.isfile(fil):
                if (os.stat(fil).st_uid == u):
                    size=os.stat(fil).st_size+size
    cmd1="getent passwd {0}".format(u)
    ou1=subprocess.Popen(cmd1,stdout=subprocess.PIPE,shell=True).communicate()[0].strip().split(':')[0]
    print size,ou1
~                                                                                                                                             
~                    

相关内容