私は、特定のディレクトリ内のすべてのユーザーのディスク使用量を分析するためのスクリプト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
その後、2番目の列を人間が読めるサイズに変換しました。
awk '{ print $2 }' example.tmp | numfmt --to=iec-i --suffix=B --padding=7
ただし、前の列があった場所に再びマージすることはできません。合計numfmt
にコマンドを直接挿入する方法はありますか?awk
私は "awk"コマンドが少し弱い方だから不足しているコードを許してください。
答え1
フォーマットを2番目のフィールドに直接制限するオプションを使用すると、--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で特定の値を適用する必要がある場合は、numfmt
単純な場合には機能しますが、不要なバリエーションは次のとおりです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
~
~