Я могу перечислить все каталоги на
find ./ -type d
Я попытался перечислить содержимое каждого каталога и подсчитать количество файлов в каждом каталоге, используя следующую команду
find ./ -type d | xargs ls -l | wc -l
Но это суммировало общее количество строк, возвращаемых
find ./ -type d | xargs ls -l
Есть ли способ подсчитать количество файлов в каждом каталоге?
Предполагая, что у вас есть поиск GNU, пусть он найдет каталоги и пусть bash сделает все остальное:
find . -type d -print0 | while read -d '' -r dir; do
files=("$dir"/*)
printf "%5d files in directory %s\n" "${#files[@]}" "$dir"
done
find . -maxdepth 1 -type d | sort
; сделать у = find $x | wc -l
; эхо $ x, $ y; сделанный
Это печатает количество файлов в каталоге для текущего уровня каталогов:
du -a | cut -d/ -f2 | sort | uniq -c | sort -nr
du -a | sed '/.*\.\/.*\/.*/!d' | cut -d/ -f2 | sort | uniq -c
. Добавить | sort -nr
для сортировки по количеству, а не по имени каталога.
Вы можете найти все файлы, удалить имена файлов, оставив строку, содержащую только имя каталога для каждого файла, и затем подсчитать количество раз, когда появляется каждый каталог:
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/
Вторая замена захватывает файлы непосредственно в текущем каталоге; они не имеют косой черты в конце, и они заменяются на ./
. Сортировка и подсчет затем работают только по числу имен.
find
. Некоторые могут: если есть файл dir1/dir2/dir3/file1
, но dir1/dir2
содержит только подкаталоги (без простых файлов), то вы можете определить его наличие. Но если у dir1/dir4
нет файлов, его имя просто не появляется.
Вот один из способов сделать это, но, вероятно, не самый эффективный.
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
bash
, ls
, wc
) для каждого каталога, найденного командой find
.
У любого другого решения есть один недостаток.
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
: подсчитайте строкиfind -type d -readable -exec sh -c 'ls -1UA "$1" | wc -l | tr -d "\n" ; printf "\t%s\n" "$1" ' sh {} ';' | sort -n
Это также можно сделать с помощью 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 для этого каталога и подсчет строк
Слегка измененная версия ответа Себастьяна с использованием 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 .
найти. -type f -printf '% h\n' | сортировать | uniq -c
дает, например:
5 .
4 ./aln
5 ./aln/iq
4 ./bs
4 ./ft
6 ./hot
Я живу здесь, для будущего напоминания
ls |parallel 'echo {} && ls {}|wc -l'
Это должно вернуть имя каталога, за которым следует количество файлов в каталоге.
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, и вам нужно экспортировать функцию, определенную в текущей области, в Новая оболочка явно.
./dir1/dir2/dir3
(подсчет всех файлов в dir1
и его подкаталогах вместе, а не подсчет файлов в dir1/dir2/dir3
отдельно от тех, что в dir1/dir2
и оба отдельно от тех, что в /dir1
).
ncdu - это интерактивный анализатор использования диска, который может отображать количество файлов в подкаталогах. Нажмите c
чтобы показать количество детей.
find . -type f | cut -d/ -f2 | sort | uniq -c
find. -type f
find. -type f
найти все элементы файла типаcut -d / -f2
чтобы вырезать их определенную папкуsort
их список foldernamesuniq -c
возвращает количество раз, которое было подсчитано каждым именемПростой способ рекурсивного поиска файлов заданного типа. В этом случае файлы .jpg для всех папок в текущем каталоге:
find. -name *.jpg -print | wc -l
Я объединил ответ @glenn jackman и ответ @pcarvalho (в списке комментариев что-то не так с ответом pcarvalho, потому что дополнительная функция управления стилем символа ' ' '(backtick)).
Мой скрипт может принимать path в качестве дополнения и сортировать список каталогов как 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, и я надеюсь, что он поможет вам ^ _ ^
Это даст общий счет.
for file in */; do echo "$file -> $(ls $file | wc -l)"; done | cut -d ' ' -f 3| py --ji -l 'numpy.sum(l)'
Я пробовал с некоторыми из других здесь, но в итоге оказалось, что вложенные папки включены в число файлов, когда мне нужны файлы. Это печатает ./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
./
?