Я нахожусь в каталоге: /home/john/my_test_files/
и в каталоге есть 100 папок:
folder1
folder2
folder3
...
folder100
, какую команду я бы использовал, чтобы напечатать список папок и количество файлов каждой из них рядом , Примерно так:
folder1 25
folder2 78
folder3 34
...
folder100 88
где folder1
содержит 25 файлов, folder2
- 78 файлов и т. Д.
Я уверен, что это что-то базовое, но я не мог не могу найти хороший ответ ...
Вот одно относительно медленное решение, которое обеспечивает хороший вывод :) Поместите следующую функцию у основания Вашего ~/.bashrc
файл. Затем откройте новое окно терминала или действительно получите файл команд выполнения: . ~/.bashrc
.
count_in() {
# set the current directory as default value
local paths="$PWD"; echo
# read the user's input as array when it is provided
[[ ! -z ${@+x} ]] && local paths=( "$@" )
# loop over the user's input
for path in "${paths[@]}"
do
# test whether this is a directory
[[ ! -d $path ]] && { echo -e "'$path' is not a directory.\n"; break; }
# output color table header for each top level directory
printf '\e[1;34m%-6s%-6s%-6s%s\e[m\n' "total" "files" "dirs" "analyzed directory"
# analyse the top level data
total=$(find "$path/" -mindepth 1 -maxdepth 1 | wc -l)
files=$(find "$path/" -mindepth 1 -maxdepth 1 -type f | wc -l)
dirs=$(find "$path/" -mindepth 1 -maxdepth 1 -type d | wc -l)
# outpot the top level data
printf '%-6d%-6d%-6d%s\n' "$total" "$files" "$dirs" "$path"
# output color table separator for the inner directories
printf '\e[1;96m%-6s%-6s%-6s%s\e[m\n' "total" "files" "dirs" "sub dir name"
# for each inner directory
while IFS='' read -r dir
do
# analyse a inner directory's data
total=$(find "$dir" -mindepth 1 -maxdepth 1 | wc -l)
files=$(find "$dir" -mindepth 1 -maxdepth 1 -type f | wc -l)
dirs=$(find "$dir" -mindepth 1 -maxdepth 1 -type d | wc -l)
# outpot the inner directory's data
printf '%-6d%-6d%-6d%s\n' "$total" "$files" "$dirs" "$(basename "$dir")"
done <<< $(find "$path/" -mindepth 1 -maxdepth 1 -type d -print)
echo
done
}
Затем используют эти count_in
функция как команда оболочки:
count_in # will analyse the current directory
count_in /path1 /path2
Демонстрационный вывод:
spas@Desktop:~$ count_in Pictures ~/Videos 'Something else'
total files dirs analyzed directory
9 3 6 Pictures
total files dirs sub dir name
19 19 0 Life Hacks
6 6 0 GIF
55 54 1 Wallpapers
20 18 2 Avatars
173 31 142 Photos
3 2 1 Icons
total files dirs analyzed directory
6 0 6 /home/spas/Videos
total files dirs sub dir name
66 0 66 Movies
11 0 11 Documentary.and.Conspiracy
7 7 0 .fun
16 2 14 Science.and.SciFi
2 2 0 Fun
2 1 1 Audio.Books
'Something else' is not a directory.
du -s --inodes *
приходит на ум (--inodes
, опция только доступна в более новых версиях человечности, я верю в 16,04 и более новый). Это распечатает что-то как
4 logs
1 pom.xml
140 src
323 target
, число перед каталогом/именами файлов является количеством файлов и каталогов в каталоге включая сам каталог.
Для иллюстрирования числа мы взглянули на logs
каталог.
$ find logs
logs
logs/2019-11-17-2.log.gz
logs/latest.log
logs/2019-11-17-1.log.gz
$ find logs | wc -l
4
Вы видите, что каталог содержит 3 файла плюс сам каталог, дает 4, как замечено в du
вывод.
знать, что подсчет строк в find
вывод не является надежным способом определить количество файлов, поскольку имена файлов, содержащие новые строки, рассчитали бы дважды. В моем простом примере это не проблема, но в Вашем случае этот метод не мог бы быть надежным. du
работы независимо от любых специальных символов в именах файлов.
Это зависит немного, под чем Вы подразумеваете файлы
, Если Вы хотите считать все нескрытые объекты (файлы / каталоги / символьные ссылки) - то же, как Вы видели бы с простым ls
команда - Вы могли сделать цикл оболочки как это:
shopt -s nullglob
for d in */; do set -- "$d"/*; printf '%s\t%d\n' "$d" "$#"; done
Это использует *
шарик для расширения списка объектов в каждом каталоге, плюс set
оболочка, встроенная для присвоения результата списку позиционных параметров оболочки - чье количество доступно в специальной переменной $#
, Если Вы не хотите запаздывающую наклонную черту в выводе, изменение "$d"
в операторе печати к "${d%/}". To pretty-print the results, pipe them through
столбец-t':
shopt -s nullglob
for d in */; do set -- "$d"/*; printf '%s\t%d\n' "${d%/}" "$#"; done | column -t
можно включать скрытые объекты путем установки dotglob
опция оболочки.