これは私の作業コードですが、最適化されていないと思います。これよりも早く作業を完了する方法が必要です。
find . -type f -iname '*.py' -printf '%h\0' |
sort -z -u |
xargs -r -0 -I{} sh -c '
find "{}" -maxdepth 1 -type f -iname "*.py" -print0 |
xargs -r -0 du -sch |
tail -1 |
cut -f1 |
tr "\n" " "
echo -e "{}"' |
sort -k1 -hr |
head -50
目的は、含まれているすべてのディレクトリを再帰的に検索し、*.py
各ディレクトリの名前ですべてのファイルの合計サイズを印刷し、*.py
サイズの逆順に並べ替えてから最初の50を表示することです。
このコードをパフォーマンスの面で改善しながらも同じ出力を維持する方法についてのアイデアはありますか?
編集する:
次の例では、提案をテストしました。47GB total: 5805 files
残念ながら、すべての提案が同じ指針に従うわけではないので、最初から最後まで比較することはできません。合計サイズはディスク使用量で、区切り文字は空白でなければなりません。形式は次のようにする必要があります。numfmt --to=iec-i --suffix=B
次の4つはソートされた出力ですが、Davidは実際のディスク使用量ではなくファイルの累積サイズを示しています。しかし、彼の改善は顕著に改善されました。 9.5倍以上速くなりました。 StéphaneとIsaacのコードは参照コードより約32倍速いので、非常に近い勝者です。
$ time madjoe.sh
real 0m2,752s
user 0m3,022s
sys 0m0,785s
$ time david.sh
real 0m0,289s
user 0m0,206s
sys 0m0,131s
$ time isaac.sh
real 0m0,087s
user 0m0,032s
sys 0m0,032s
$ time stephane.sh
real 0m0,086s
user 0m0,013s
sys 0m0,047s
残念ながら、次のコードは最大50個の結果をソートまたは表示しません。さらに、以前にIsaacのコードと比較すると、次のコードはIsaacの改善より約6倍遅くなります。
$ time hauke.sh
real 0m0,567s
user 0m0,609s
sys 0m0,122s
ベストアンサー1
配列のすべてのディレクトリ合計を収集し、最後にすべてを印刷して@HaukeLagingのソリューションを簡素化しました(GNU awkを使用)。また、numfmt
(最終的に)1回の呼び出しのみが必要です。
#!/bin/sh
find . -type f -iname '*.py' -printf '%s %h\0' |
awk 'BEGIN { RS="\0"; };
{ gsub(/\\/,"&&"); gsub(/\n/,"\\n");
size=$1; sub("[^ ]* ",""); dirsize[$0]+=size }
END { PROCINFO["sorted_in"] = "@val_num_desc";
i=0;
for ( dir in dirsize ) { if(++i<=50)
{ print dirsize[dir], dir; }else{ exit }
}
} ' | numfmt --to=iec-i --suffix=B
これは、ディスク使用量ではなくpyファイルの累積見かけのサイズを生成し、ディレクトリのサブディレクトリにあるファイルを合計することを防ぎます。