Как посчитать все файлы рекурсивно через директории

Вопрос или проблема

Я хочу узнать, сколько файлов в подкаталогах, чтобы понять, где используется все количество инодов в системе. Примерно так же, как это делается для использования дискового пространства

du -sh /*

что даст мне информацию о занятом месте в директориях от корня, но в данном случае я хочу узнать количество файлов, а не размер.

find . -maxdepth 1 -type d | while read -r dir
do printf "%s:\t" "$dir"; find "$dir" -type f | wc -l; done

Спасибо Гилльу и xenoterracide за исправления в плане безопасности и совместимости.

Первая часть: find . -maxdepth 1 -type d вернет список всех директорий в текущем рабочем каталоге. 
(Предупреждение: -maxdepth это расширение GNU
и может отсутствовать в версиях find, не относящихся к GNU.) 
Это передается в…

Вторая часть: while read -r dir; do
(показано выше как while read -r dir(новая строка)do) начинает цикл while – пока открыта передача в while (что происходит до тех пор, пока не будет отправлен весь список директорий), команда read поместит следующую строку в переменную dir. Затем продолжается…

Третья часть: printf "%s:\t" "$dir" распечатывает строку в $dir
(которая содержит одно из названий директорий) с последующим двоеточием и табуляцией
(но не с новой строкой).

Четвертая часть: find "$dir" -type f создает список всех файлов
внутри директории, имя которой хранится в $dir. Этот список передается в…

Пятая часть: wc -l считает количество строк, отправленных в его стандартный ввод.

Последняя часть: done просто завершает цикл while.

Таким образом, мы получаем список всех директорий в текущем каталоге. Для каждой из этих директорий мы создаем список всех файлов в ней, чтобы подсчитать их с помощью wc -l. Результат будет выглядеть так:

./dir1: 234
./dir2: 11
./dir3: 2199
...

Попробуйте find . -type f | wc -l, это посчитает все файлы в текущем каталоге, а также все файлы в подкаталогах. Обратите внимание, что все директории не будут считаться как файлы, только обычные файлы.

Вот подборка некоторых полезных команд для вывода списка (переработана на основе кода предыдущих пользователей):

Список папок с количеством файлов:

find -maxdepth 1 -type d | sort | while read -r dir; do n=$(find "$dir" -type f | wc -l); printf "%4d : %s\n" $n "$dir"; done

Список папок с ненулевым количеством файлов:

find -maxdepth 1 -type d | sort | while read -r dir; do n=$(find "$dir" -type f | wc -l); if [ $n -gt 0 ]; then printf "%4d : %s\n" $n "$dir"; fi; done

Список папок с количеством подкаталогов:

find -maxdepth 1 -type d | sort | while read -r dir; do n=$(find "$dir" -type d | wc -l); let n--; printf "%4d : %s\n" $n "$dir"; done

Список папок с ненулевым количеством подкаталогов:

find -maxdepth 1 -type d | sort | while read -r dir; do n=$(find "$dir" -type d | wc -l); let n--; if [ $n -gt 0 ]; then printf "%4d : %s\n" $n "$dir"; fi; done

Список пустых папок:

find -maxdepth 1 -type d | sort | while read -r dir; do n=$(find "$dir" | wc -l); let n--; if [ $n -eq 0 ]; then printf "%4d : %s\n" $n "$dir"; fi; done

Список непустых папок с количеством содержимого:

find -maxdepth 1 -type d | sort | while read -r dir; do n=$(find "$dir" | wc -l); let n--; if [ $n -gt 0 ]; then printf "%4d : %s\n" $n "$dir"; fi; done

Попробуйте:

find /path/to/start/at -type f -print | wc -l

в качестве отправной точки, или если вы действительно хотите пройтись только по подкаталогам каталога (и пропустить файлы в этом верхнем уровне каталога)

find `find /path/to/start/at -mindepth 1 -maxdepth 1 -type d -print` -type f -print | wc -l

du –inodes (только версия GNU)

Я не уверен, почему никто (включая меня) не знал о:

du --inodes
--inodes
      показывать информацию об использовании инодов вместо использования блоков

Я довольно уверен, что это решает проблему OP. Я начал использовать это часто, чтобы понять, где весь мусор на моих больших дисках (и перенести его на более старый диск).

Дополнительная информация

Если вы НЕ хотите рекурсировать (что может быть полезно в других ситуациях), добавьте

-S, --separate-dirs

Если у вас установлен ncdu (обязательно при необходимости очистки), просто введите c, чтобы “Переключить отображение количества дочерних элементов”. И C, чтобы “Сортировать по элементам”.

Следующее решение считает фактическое количество используемых инодов, начиная с текущей директории:

find . -print0 | xargs -0 -n 1 ls -id | cut -d' ' -f1 | sort -u | wc -l

Чтобы получить количество файлов одной и той же подгруппы, используйте:

find . | wc -l

Для решений, исследующих только подкаталоги, не принимая в расчет файлы в текущем каталоге, вы можете обратиться к другим ответам.

Попробуйте это:

find -type d -print0 | xargs -0 -I {} sh -c 'printf "%s\t%s\n" "$(find "{}" -maxdepth 1 -type f | wc -l)" "{}"'

Это должно работать нормально, если только имена файлов не содержат новых строк.

OS X 10.6 не работает с командой в принятом ответе, поскольку она не указывает путь для find. Вместо этого используйте:

find . -maxdepth 1 -type d | while read -r dir; do printf "%s:\t" "$dir"; find "$dir" -type f | wc -l; done

Я знаю, что опоздал на вечеринку, но я думаю, что это чистое решение bash (или другой оболочки, которая принимает двойное звездное глобальное выражение) может быть намного быстрее в некоторых ситуациях:

shopt -s globstar    # включить ** глобус в bash
for dir in */; do a=( "$dir"/**/* ); printf "%s\t%s\n" "$dir:" "${#a[*]}"; done

вывод:

d1/:    302
d2/:    24
d3/:    640
...

Используйте эту рекурсивную функцию, чтобы перечислить общее количество файлов в директории рекурсивно, до определенной глубины (она считает файлы и директории на всех уровнях, но показывает общее количество до max_depth):

#!/bin/bash
# set -x

export max_depth="2"
export found_files="/tmp/found_files.txt"

function get_all_the_files()
{
    depth="$1";
    base_directory="$2";

    if [[ "$depth" -ge "$max_depth" ]];
    then
        return;
    fi

    find "$base_directory" -maxdepth 1 -type d | while read -r inner_directory
    do
        printf "%s\t%s\n" "$(find "$inner_directory" | wc -l)" "$inner_directory" | tee -a "$found_files";
        if [[ "w$(realpath "$base_directory")" != "w$(realpath "$inner_directory")" ]];
        then
            get_all_the_files "$(( depth + 1 ))" "$inner_directory";
        fi;
    done;
}

rm -f "$found_files"
get_all_the_files 0 /tmp/

printf '\nПоиск файлов завершен, сортировка всех:\n'
sort --version-sort "$found_files"

Внутри папки (директории), которую вы хотите подсчитать (cd /my/dir), вы можете сделать следующее:

  1. Чтобы подсчитать все папки и файлы:
    find . | wc -l
  2. Чтобы подсчитать только папки (каталоги):
    find . -type d | wc -l
  3. Чтобы подсчитать только файлы:
    find . -type f | wc -l

Таким образом, вы сможете проверить, что: папки (2) + файлы (3) = всего (1)


Некоторые пояснения:

  • Команда find . будет выводить каждую из всех папок (директорий) и файлов по одному в строку.
    • Параметр: -type d говорит о том, чтобы выводить только dиректории (папки)
    • Параметр: -type f говорит о том, чтобы выводить только fайлы.
  • Команда wc -l должна означать что-то вроде: подсчет слов с параметром: строки.

Ответ или решение

Чтобы подсчитать количество файлов рекурсивно через директории, можно воспользоваться командой find, которая является мощным инструментом для поиска файлов и директорий в Unix-подобных системах.

Основные команды

  1. Подсчет всех файлов во всех подкаталогах:
    Если вы хотите подсчитать общее количество файлов в текущем каталоге и всех его подкаталогах, используйте следующую команду:

    find . -type f | wc -l

    Эта команда ищет все файлы (-type f) начиная с текущей директории (.) и передает результат в wc -l, который подсчитывает количество строк (то есть файлов).

  2. Подсчет файлов в определенной директории с рекурсией:
    Если вам нужно считать файлы только в определенной директории и ее подкаталогах:

    find /путь/к/директории -type f | wc -l
  3. Подсчет файлов в подкаталогах с пропуском верхнего уровня:
    Чтобы подсчитать только файлы в подкаталогах, не учитывая файлы в самом верхнем уровне:

    find /путь/к/директории -mindepth 1 -type f | wc -l

Расширенные команды

Если вы хотите и видеть количество файлов в каждом отдельном подкаталоге, можно использовать следующий скрипт:

find . -maxdepth 1 -type d | while read -r dir; do 
    count=$(find "$dir" -type f | wc -l)
    printf "%s: %d\n" "$dir" "$count"
done

Этот скрипт проходит по всем директориям в текущем каталоге и выводит количество файлов в каждой директории.

Использование команды du для подсчета инодов

Для получения информации о количестве использованных инодов можно использовать следующую команду (GNU-версия du):

du --inodes /путь/к/директории

Эта команда выведет количество инодов, что может быть полезно для понимания распределения файловой системы.

Возможности ncdu

Если у вас установлен ncdu, вы можете использовать его для визуализации использования дискового пространства и файлов. Просто запустите ncdu, и затем можно будет переключить режимы отображения для просмотра количества файлов в директориях.

Заключение

Скрипты и команды, представленные выше, дают возможность гибко анализировать количество файлов в директориях и оценивать использование инодов. Вы можете адаптировать их под свои нужды в зависимости от структуры ваших каталогов и ваших целей.

Оцените материал
Добавить комментарий

Капча загружается...