Kabuktaki uzantıya göre toplam dosya boyutunu hesaplama


13

Lucene indeksleri içeren bir dizi dizinimiz var. Her dizin, farklı dosya türlerinin (uzantıya göre farklılaştırılmış) bir örneğidir:

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

(yaklaşık 10 farklı uzantı)

Dosya uzantısına göre toplam almak istiyoruz, örneğin:

.frq     21234
.fnm     34757
..

Du / awk / xargs çeşitli kombinasyonları denedim ama tam olarak bunu yapmak zor.


Bu sorunun cevabını bu yazıda
bulacaksınız

Her dosya türünün toplam boyutunu veya her dosya türünün toplam sayısını bilmek ister misiniz?
user9517 7:12

Toplam dosya boyutu lütfen.
barnybug

Yanıtlar:


19

Herhangi bir uzantı için bir kullanım

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

bu türün toplam dosya boyutunu elde etmek için.

Ve biraz düşündükten sonra

#!/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

Hangi boyutu bulunan her dosya türü bayt cinsinden çıktı.


Teşekkürler, herhangi bir uzantı tarafından özetlenen bir şey arıyordu (örneğin sıralamak için kullanışlı olacağı için)
barnybug

Güncellememi kontrol et.
user9517 7:12

çok teşekkürler. awk bazı sayılar için bilimsel çıktı üretir, bu devre dışı bırakılabilir mi: .fdt 3.15152e + 10
barnybug

1
sadece düz tamsayı numaraları vermek için biraz tweaked: find. -adi "* $ {ft}" -print0 | xargs -0 du -c | toplam grep | awk '{print $ 1}'
barnybug

1
-inameDosyayı genişletme arama durumunu duyarsız hale getirmek için kullanmak isteyebilirsiniz .
Aaron Copley

6

Bash version4 ile, sadece çağrı gerekir find, lsve awkgerekli değildir:

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

Bu komut dosyası, sekme karakterli dosya adlarıyla iyi çalışmaz. Değişen read name sizeiçin read size nameve -printf "%f\t%s\n"için -printf "%s\t%f\n"bunu düzeltmek gerekir.
matt

1
Ayrıca bu komut dosyasının uzantısız dosyalarla iyi çalışmadığını unutmayın. Tüm dosya adını uzantı olarak ele alır. Bunu önlemek için if [ "$name" == "$ext" ]; then ext="*no_extension*"; fisonra ekleyin ext=${name##*.}. Bu içine uzantısı olmadan tüm dosyaları koyacağız *no_extension*(kullanıyorum grubun *no_extension*çünkü *dosya adında geçerli bir karakter değildir)
mat

4

.Diziye kaydedilen her ikinci sütun ve son bölüm (uzantı) kaydedildi.

#!/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

o zaman her uzantı toplam bayt cinsinden var.

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

1

Çok sayıda dosyayla çalışmak için Iain'in betiğini daha hızlı bir sürümle genişletme.

#!/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

Bu iki komutu kullanarak çözdüm:

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

0

soruya cevap sürümüm:

#!/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

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.