Подтвердить что ты не робот

Как подсчитать количество файлов в каждом каталоге?

Я могу перечислить все каталоги на

find ./ -type d

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

find ./ -type d | xargs ls -l | wc -l

Но это суммировало общее количество строк, возвращаемых

find ./ -type d | xargs ls -l

Есть ли способ подсчитать количество файлов в каждом каталоге?

4b9b3361

Ответ 1

Предполагая, что у вас есть поиск GNU, пусть он найдет каталоги и пусть bash сделает все остальное:

find . -type d -print0 | while read -d '' -r dir; do
    files=("$dir"/*)
    printf "%5d files in directory %s\n" "${#files[@]}" "$dir"
done

Ответ 2

Это печатает количество файлов в каталоге для текущего уровня каталогов:

du -a | cut -d/ -f2 | sort | uniq -c | sort -nr

Ответ 3

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

find . -type f |
sed 's%/[^/]*$%%' |
sort |
uniq -c

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


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

find . -type f |
sed -e 's%^\(\./[^/]*/\).*$%\1%' -e 's%^\.\/[^/]*$%./%' |
sort |
uniq -c

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

./dir1/dir2/file1

заменяется на

./dir1/

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

Ответ 4

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

find -type d -print0 | xargs -0 -n1 bash -c 'echo -n "$1:"; ls -1 "$1" | wc -l' --

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

./c/fa/l:0
./a:4
./a/c:0
./a/a:1
./a/a/b:0

Ответ 5

У любого другого решения есть один недостаток.

find -type d -readable -exec sh -c 'printf "%s " "$1"; ls -1UA "$1" | wc -l' sh {} ';'

Пояснение:

  • -type d: нас интересуют каталоги.
  • -readable: нам нужны только их, если можно перечислить файлы в них. Обратите внимание, что find будет по-прежнему выдавать ошибку при попытке поиска в них большего количества каталогов, но это предотвращает вызов для них -exec.
  • -exec sh -c BLAH sh {} ';': для каждого каталога запустите этот script фрагмент, с $0 установите для sh и $1 значение для имени файла.
  • printf "%s " "$1": портативно и минимально печатать имя каталога, за которым следует только пробел, а не новая строка.
  • ls -1UA: перечислите файлы, по одному в каждой строке, в порядке каталога (во избежание остановки соединения), исключая только специальные каталоги . и ..
  • wc -l: подсчитайте строки

Ответ 6

find . -type f | cut -d/ -f2 | sort | uniq -c
  • find. -type f, чтобы найти все элементы файла типа
  • cut -d/ -f2 вырезать их определенную папку
  • sort для сортировки списка папок с именами
  • uniq -c возвращает количество раз, которое было подсчитано каждым именем

Ответ 7

Это также можно сделать с помощью looping over ls вместо find

for f in */; do echo "$f -> $(ls $f | wc -l)"; done

Пояснение:

for f in */; - цикл по всем каталогам

do echo "$f -> - распечатать каждое имя каталога

$(ls $f | wc -l) - вызов ls для этого каталога и подсчет строк

Ответ 8

Слегка измененная версия ответа Себастьяна с использованием find вместо du (чтобы исключить накладные расходы, связанные с размером файла, которые du должен выполнять и которые никогда не используются):

 find ./ -mindepth 2 -type f | cut -d/ -f2 | sort | uniq -c | sort -nr

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

  234 dir1
  123 dir2
    1 file1
    1 file2
    1 file3
      ...
    1 fileN

(очень похоже на вариант du -based)

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

{ find ./ -mindepth 2 -type f | cut -d/ -f2 | sort && find ./ -maxdepth 1 -type f | cut -d/ -f1; } | uniq -c | sort -nr

Вывод будет выглядеть следующим образом:

  234 dir1
  123 dir2
   42 .

Ответ 9

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

findfiles() {
    echo "$1" $(find "$1" -maxdepth 1 -type f | wc -l)
}

export -f findfiles

find ./ -type d -exec bash -c 'findfiles "$0"' {} \;

Пример вывода:

./ 6
./foo 1
./foo/bar 2
./foo/bar/bazzz 0
./foo/bar/baz 4
./src 4

export -f требуется, потому что аргумент -exec find не позволяет выполнять функцию bash, если вы явно не вызываете bash, и вам нужно экспортировать функцию, определенную в текущей области, в Новая оболочка явно.

Ответ 10

Я живу здесь, для будущего напоминания

ls |parallel 'echo {} && ls {}|wc -l'

Ответ 11

найти. -type f -printf '% h\n' | сортировать | uniq -c

дает, например:

  5 .
  4 ./aln
  5 ./aln/iq
  4 ./bs
  4 ./ft
  6 ./hot

Ответ 12

Я объединил @glenn jackman answer и @pcarvalho answer (в списке комментариев что-то не так с ответом pcarvalho, потому что дополнительная функция управления стилем символа '''(backtick)).

Мой сценарий может принимать путь в качестве дополнения и сортировать список каталогов как ls -l, а также он может решить проблему "пробела в имени файла".

#!/bin/bash
OLD_IFS="$IFS"
IFS=$'\n'
for dir in $(find $1 -maxdepth 1 -type d | sort); 
do
    files=("$dir"/*)
    printf "%5d,%s\n" "${#files[@]}" "$dir"
done
FS="$OLD_IFS"

Мой первый ответ в stackoverflow, и я надеюсь, что он может кому-то помочь ^ _ ^

Ответ 13

Я пробовал с некоторыми из других здесь, но в итоге оказалось, что вложенные папки включены в число файлов, когда мне нужны файлы. Это печатает ./folder/path<tab>nnn с количеством файлов, не включая подпапки, для каждой подпапки в текущей папке.

for d in `find . -type d -print` 
do 
  echo -e "$d\t$(find $d -maxdepth 1 -type f -print | wc -l)"
done

Ответ 14

Простой способ рекурсивного поиска файлов заданного типа. В этом случае файлы .jpg для всех папок в текущем каталоге:

find. -name *.jpg -print | wc -l

Ответ 15

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

Ответ 16

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

find . -type f | sed -e 's/.*\.//' | sort | uniq -c | sort -n | grep -Ei '(tiff|bmp|jpeg|jpg|png|gif)$'

Кредиты: https://unix.stackexchange.com/a/386135/354980

Ответ 17

Это даст общий счет.

for file in */; do echo "$file -> $(ls $file | wc -l)"; done | cut -d ' ' -f 3| py --ji -l 'numpy.sum(l)'