Obliczanie całkowitego rozmiaru pliku według rozszerzenia w powłoce

13

Mamy zestaw katalogów zawierających indeksy lucenu. Każdy indeks jest mieszanką różnych typów plików (w zależności od rozszerzenia), np .:

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

(to około 10 różnych rozszerzeń)

Chcielibyśmy uzyskać sumę według rozszerzenia pliku, np .:

.frq     21234
.fnm     34757
..

Próbowałem różnych kombinacji du / awk / xargs, ale znalezienie tego jest trudne.

Barnybug
źródło
Odpowiedź na ten problem znajdziesz w tym poście: serverfault.com/questions/183431
Blueicefield,
Czy chcesz poznać całkowity rozmiar każdego typu pliku lub całkowitą liczbę każdego rodzaju pliku?
user9517
Całkowity rozmiar pliku proszę.
barnybug

Odpowiedzi:

19

Do dowolnego rozszerzenia możesz użyć

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

aby uzyskać całkowity rozmiar pliku dla tego typu.

I po namyśle

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

Który wyświetli rozmiar w bajtach każdego znalezionego typu pliku.

Iain
źródło
Dzięki, szukałem czegoś, co podsumowałoby dowolne rozszerzenie (jak przydałoby się np.
Posortować
Sprawdź moją aktualizację.
user9517
wielkie dzięki. awk produkuje wyniki naukowe dla niektórych liczb, czy można to wyłączyć: .fdt 3.15152e + 10
barnybug
1
lekko poprawione, aby podawać zwykłe liczby całkowite: znajdź. -nazwa „* $ {ft}” -print0 | xargs -0 du -c | grep ogółem | awk '{print $ 1}'
barnybug
1
Może chcesz użyć, -inameaby rozróżnić wielkość liter w wyszukiwaniu rozszerzenia pliku.
Aaron Copley,
6

Z bash version4, wystarczy do wywołania find, lsa awknie jest to konieczne:

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
Glenn Jackman
źródło
Ten skrypt nie działa dobrze z nazwami plików ze znakiem tabulacji. Zmieniających read name sizesię read size namei -printf "%f\t%s\n"do -printf "%s\t%f\n"powinien to naprawić.
mat
1
Zauważ też, że ten skrypt nie działa dobrze z plikami bez rozszerzenia. Traktuje całą nazwę pliku jako rozszerzenie. Dodaj if [ "$name" == "$ext" ]; then ext="*no_extension*"; fipo, ext=${name##*.}jeśli chcesz temu zapobiec. Spowoduje to umieszczenie wszystkich plików bez rozszerzenia w *no_extension*grupie (używam, *no_extension*ponieważ *nie jest prawidłowym znakiem w nazwie pliku)
mat
4

Co druga kolumna podzielona przez .ostatnią część (rozszerzenie) zapisaną w tablicy.

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

to masz całkowity rozmiar każdego rozszerzenia w bajtach.

60055 gemspec
321991 txt
2075312 html
2745143 rb
13387264 gem
47196526 jar
Selman Ulug
źródło
1

Rozszerzenie na skrypt Iaina z szybszą wersją do pracy z dużą liczbą plików.

#!/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
MilesF
źródło
0

Rozwiązałem za pomocą tych dwóch poleceń:

FILES=$(find . -name '*.c')
stat -c %s ${FILES[@]} | awk '{ sum += $1 } END { print ".c" " " sum }'
c4f4t0r
źródło
0

moja wersja odpowiedzi na pytanie:

#!/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
Isterklister
źródło
0

Wypróbuj Crab ( http://etia.co.uk/ ) - to narzędzie wiersza polecenia, które pozwala na zapytanie systemu plików za pomocą SQL.

Jacek Lampart
źródło