ディレクトリ(例/home/various/
:)と複数のサブディレクトリ(例:/home/various/foo/
と/home/various/ber/
)があります。/home/various/kol/
/home/various/whatever/
各ファイル拡張子の内容を分析して合計を表示するコマンドを実行できますか?
- フルサイズ
- ファイル数
端末にすべてのファイル拡張子を手動で入力したくないとしましょう。部分的には、内部のすべてのファイル拡張子を(繰り返し)知らないからです/various/
。
次のような出力が良いでしょう。
*.txt 23 files, 10.2MB
*.pdf 8 files, 23.2MB
*.db 3 files, 2.3MB
*.cbz 24 files, 2.3GB
*.html 2,508 files, 43.9MB
*.readme 13 files, 4KB
答え1
基本コード
duext() {
case "$1" in
-* )
set "./$1"
esac
POSIXLY_CORRECT= find "${1-.}" -type f -exec du {} + | awk '
{
sz=$1
$1=""
sub("^ *","")
sub("^.*/","")
sub("^\\.","")
w=split($0,a,".")
e=tolower(w==1?"*":"*."a[w])
s[e]+=sz
n[e]+=1
}
END {
for (e in s) print 512*s[e]"\t"n[e]"\t"e
}'
}
使用法: duext path
。デフォルト値path
はです.
。この関数はsh
互換性のあるシェルで実行する必要があります。
この関数は、次の形式の行を生成します。
s<tab>n<tab>e
ここでs
、使用されるディスクサイズ(バイト単位)、n
ファイル数、e
拡張子です。解析を最適化することを決めたので、要求された出力とは異なります。 「拡張子」と呼ぶのは *nix のファイル名の一部にすぎません。ファイル名にはスペースまたはタブ文字を含めることができます。e
行の末尾に(スペースまたはタブを含めることができます)配置すると、他のフィールドを確実に識別できます。たとえば、次のようにサイズで簡単に並べ替えることができます。
duext /home/various/ | sort -rn -k1,1 # optionally: … | column -t
メモ:
- パス名に改行を使用すると、誤った結果が発生します。
POSIXLY_CORRECT= du …
使用されているディスクサイズを取得する移植可能な方法。 512バイト単位で報告されるため、コードの後半に512*s[e]
あります。awk
GNUはdu
いくつかの興味深いオプション(コード調整が必要な場合があります)を提供します--apparent-size
。awk
sub("^\\.","")
名前の先行点を拡張区切り文字として扱わない役割を担います。実際に.nfo
は拡張子nfo
。これが望ましくない場合は、この行を削除してください。- コードは、空の拡張子(たとえば
foo.
)と拡張子のない(foo
)を区別します。前者はとして報告され*.
、後者はとして報告されます*
。 - コードは大文字と小文字を区別しません。
tolower
大文字と小文字を区別するには、削除してください。 - ハードリンクによって結果が歪むことがあります。
du
ファイルがいくつかの記録されたファイルへのハードリンクである場合は、そのファイルを無視することも、無視しないこともあります。また、(回避するために)必要な回数だけfind … -exec du {} +
実行すると、ハードリンクされたファイルが同じファイルに転送されたり、転送されないことがあります。 (GNUの移植不可能なオプション)を使用するか、以下を実行して各ファイルを強制的に計算できます。ファイルごとに1つ。ハードリンク: 。ハードリンクを一度だけ安定して計算するには、別のアプローチ(GNUの単一インスタンスと?)が必要です。通常、異なる拡張子を持つハードリンクを持つことが可能です。各ハードリンクを個別に計算したい場合は問題ありませんが、1つのファイルとして計算したい場合は、割り当てられた拡張子は定義されません。du
argument list too long
du
du -l
du
du
find … -exec du {} \;
du
--files0-from=
カスタムフォーマット
MB
何を言っているのか分からないメガバイトまたはメガバイト、私の考えは後者のようだ。次のコードは目的の形式に変換する必要があります。
yourformat() { awk '
function human(x) {
if (x<1000) {return x} else {x/=1000}
s="kMGTEPZY";
while (x>=1000 && length(s)>1)
{x/=1000; s=substr(s,2)}
return int(10*x+0.5)/10 substr(s,1,1)
}
{
s=$1; n=$2
$1=""; $2=""
sub("^ ","")
print $0" "n" file"(n==1?"":"s")", "human(s)"B"
}'
}
(注:human(x)
から抜粋この回答そして調整をしました。 )
次のように使用してください。
duext /home/various/ | yourformat
duext
内部で使用されているので、awk
パイプを使用してyourformat
使用しますawk
。通常、awk
単一の関数で代わりに使用できます。それでも別のsを使用すると、たとえば、単一のシェル関数または関数間のパイプラインにawk
配置できます。 (または少なくともGNUで)sort …
一種のソートを実装することは可能ですが、ホイールを再発明することは意味がありません。 IMOは最初の出力を解析しやすく保つのが正しいことです。だから申請してくださいawk
awk
awk
どのフィルタリングと書式設定は後で実行されます。
column -t
使用できるようにフォーマットを改善してみましょう。 1024の買収はどうですか?
myformat() { awk '
function human(x) {
if (x<1000) {return x" "} else {x/=1024}
s="kMGTEPZY";
while (x>=1000 && length(s)>1)
{x/=1024; s=substr(s,2)}
return int(10*x+0.5)/10" "substr(s,1,1)"i"
}
{
s=$1; n=$2
$1=""; $2=""
sub("^ ","")
print $0"\t"n" file"(n==1?"":"s")"\t"human(s)"B"
}'
}
それから:
duext /home/various/ | sort -nr -k1,1 | myformat | column -t -s "$(printf '\t')"
メモ:
"$(printf '\t')"
タブ文字を取得する移植可能な方法です。 Bashなどの一部のシェルでは$'\t'
同じことが行われます。column
それ自体は移植性がありません。- タブ文字を含む拡張子は書式を破損します。しかし、彼らは非常にまれです。
正直なところ、私はこのソリューションが本当に気に入って維持します。due
後で使用できるようにスクリプトを作成しました。
#!/bin/sh
duext() {
…
}
myformat {
…
}
duext "${1-.}" | sort -nr -k1,1 | myformat | column -t -s "$(printf '\t')"
答え2
これは非常に興味深い問題であり、私が作ることができる最高のスクリプトは次のとおりです。
set -e
# set -x
folder=$1
counter=$(tempfile)
# List file extensions
list_extensions() {
find "$folder" -type f |
while read filename
do
basename=${filename##*/}
ext=${basename##*.}
echo ${ext,,} # downcase extensions to prevent duplicates
done |
sort -u
}
list_extensions |
while read extension
do
size=$(find "$folder" -type f -iname "*.$extension" -fprintf $counter . -print0 |
du -hc --files0-from=- | tail -n 1 | sed -E 's/\s+total//')
count=$( wc -c < $counter )
printf "*.%-10s\t%6s files\t%10s\n" "$extension" "$count" "$size"
done
rm $counter
複雑なファイル名をサポートせずに例外が発生する可能性があり、パフォーマンスはあまり良くありませんが、うまくいきます。
出力例:
*.wma 122 files 411M
*.wpl 16 files 64K
*.xls 2 files 24K
*.xlsx 1 files 28K
*.zip 5 files 333M