シェルでの拡張子による合計ファイルサイズの計算


13

luceneインデックスを含むディレクトリのセットがあります。各インデックスは、さまざまなファイルタイプの組み合わせです(拡張子によって区別されます)。例:

0/index/_2z6.frq
0/index/_2z6.fnm
..
1/index/_1sq.frq
1/index/_1sq.fnm
..

(約10種類の拡張機能です)

ファイル拡張子ごとに合計を取得したい、例えば:

.frq     21234
.fnm     34757
..

du / awk / xargsのさまざまな組み合わせを試しましたが、これを正確に行うのは難しいと感じました。


あなたはこの記事ではその問題の答えを持っている: serverfault.com/questions/183431/...
Blueicefield

各タイプのファイルの合計サイズまたは各タイプのファイルの合計数を知りたいですか?
user9517

合計ファイルサイズをお願いします。
barnybug

回答:


19

任意の拡張機能に対して

find /path -name '*.frq' -exec ls -l {} \; | awk '{ Total += $5} END { print Total }'

そのタイプの合計ファイルサイズを取得します。

そして、いくつかの思考の後

#!/bin/bash

ftypes=$(find . -type f | grep -E ".*\.[a-zA-Z0-9]*$" | sed -e 's/.*\(\.[a-zA-Z0-9]*\)$/\1/' | sort | uniq)

for ft in $ftypes
do
    echo -n "$ft "
    find . -name "*${ft}" -exec ls -l {} \; | awk '{total += $5} END {print total}'
done

検出された各ファイルタイプのサイズをバイト単位で出力します。


おかげで、任意の拡張機能によって要約されたものを探していました(たとえば、並べ替えるのに便利です)
-barnybug

更新を確認してください。
user9517

まことにありがとうございます。awkは、いくつかの数値に対して科学的な出力を生成します。これを無効にできます。.fdt 3.15152e + 10
barnybug

1
単なる整数値を与えるためにわずかに調整しました:find -name "* $ {ft}" -print0 | xargs -0 du -c | grep合計| awk '{print $ 1}'
barnybug

1
使用する場合があります-inameファイルextenstion検索ケース小文字を区別しないを作ります。
アーロンコプリー

6

bash version4では、呼び出す必要がありますがfind、必要lsありawkません:

declare -A ary

while IFS=$'\t' read name size; do 
  ext=${name##*.}
  ((ary[$ext] += size))
done < <(find . -type f  -printf "%f\t%s\n")

for key in "${!ary[@]}"; do 
  printf "%s\t%s\n" "$key" "${ary[$key]}"
done

このスクリプトは、タブ文字を含むファイル名ではうまく機能しません。に変更read name sizeするread size name-printf "%f\t%s\n"-printf "%s\t%f\n"修正する必要があります。
マット

1
また、このスクリプトは拡張子のないファイルではうまく機能しないことに注意してください。ファイル名全体を拡張子として扱います。防止する必要がある場合はif [ "$name" == "$ext" ]; then ext="*no_extension*"; fi、後に追加しext=${name##*.}ます。これはに拡張子のないすべてのファイルを置く*no_extension*(私が使用しているグループ*no_extension*ので、*ファイル名に有効な文字ではありません)
マット

4

2列ごとに.分割され、最後の部分(拡張子)が配列に保存されます。

#!/bin/bash

find . -type f -printf "%s\t%f\n" | awk '
{
 split($2, ext, ".")
 e = ext[length(ext)]
 size[e] += $1
}

END{
 for(i in size)
   print size[i], i
}' | sort -n

次に、すべての拡張機能の合計サイズをバイト単位で取得しました。

60055 gemspec
321991 txt
2075312 html
2745143 rb
13387264 gem
47196526 jar

1

多数のファイルを処理するための高速バージョンでIainのスクリプトを拡張します。

#!/bin/bash

ftypes=$(find . -type f | grep -E ".*\.[a-zA-Z0-9]*$" | sed -e 's/.*\(\.[a-zA-Z0-9]*\)$/\1/' | sort | uniq)

for ft in $ftypes
do
    echo -ne "$ft\t"
    find . -name "*${ft}" -exec du -bcsh '{}' + | tail -1 | sed 's/\stotal//'
done


0

この2つのコマンドを使用して解決しました。

FILES=$(find . -name '*.c')
stat -c %s ${FILES[@]} | awk '{ sum += $1 } END { print ".c" " " sum }'

0

質問への回答の私のバージョン:

#!/bin/bash

date >  get_size.log
# Lists all files
find . -type f -printf "%s\t%f\n" | grep -E ".*\.[a-zA-Z0-9]*$" | sort -h | awk  '
{
        split($2, ext, ".")
        e = ext[length(ext)]
        # Checks that one extension could be found
        if(length(e) < length($2)) {
                # Check that file size are bigger than 0
                if($i > 0) {
                        # Check that extension not are integer
                        if(!(e ~/^[0-9]+$/)) {
                                size[e] += $1
                        }
                }
        }
        if(length(e) == length($2)) {
                size["blandat"] += $1
        }
}

END{
 for(i in size)
   print size[i], i
}' | sort -n >> get_size.log
echo
echo
echo The result are in file get_size.log

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.