Обчислення загального розміру файлу шляхом розширення в оболонці


13

У нас є набір каталогів, що містять люценові індекси. Кожен індекс - це суміш різних типів файлів (диференційована розширенням), наприклад:

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

Ви хочете знати загальний розмір кожного типу файлів або загальну кількість кожного типу файлів?
користувач9517

Загальний розмір файлу, будь ласка.
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

Перевірте моє оновлення.
користувач9517

щиро дякую. awk виробляє наукові результати для деяких номерів, їх можна відключити: .fdt 3.15152e + 10
barnybug

1
трохи налаштовано, щоб просто дати прості цілі числа: знайти. -name "* $ {ft}" -print0 | xargs -0 du -c | греп загальний | awk '{print $ 1}'
barnybug

1
Можливо, ви хочете використовувати їх -inameдля того, щоб зробити справу пошуку розширення файлу нечутливою.
Аарон Коплі

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*тому що *не є дійсним символом у назві файлу)
matt

4

Кожен другий стовпчик, розділений на .останню частину (розширення), збережений у масиві.

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

Це рішення:

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

Рішення, розміщене спочатку в цій публікації: Отримайте всі розширення та їх відповідний кількість файлів у каталозі


3
Це підрахунок за кількістю файлів, а не те, про що я питав - я хотів би загальну кількість.
barnybug

0

Я вирішив за допомогою цих двох команд:

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.