#!/bin/bash echo "Создание списков свойств для файлов каждого каталога." #-----------------------------------------------------------------------------------------------; prompt="Подтверждение (да/нет): " && read -erp "$prompt" line && echo -ne "\033[1A$prompt\033[K" case "${line,,}" in y | yes | д | да) echo "ПОДТВЕРЖДЕНИЕ" ;; *) echo "ОТМЕНА" && exit 0 ;; esac #-----------------------------------------------------------------------------------------------; time_ms="$(date '+%s%3N')" #-----------------------------------------------------------------------------------------------; # получаем соотношение сторон по размерам изображения => 256:135 / 64:27 / 16:9 / 8:5 / 4:3 / 1:1 function aspect_ratio { w="${1%x*}" && h="${1#*x}" if [ "$w" == "$h" ]; then w="1" && h="1" else P=(2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97) while true; do for p in "${P[@]}"; do if ((w % p == 0 && h % p == 0)); then w="$((w / p))" && h="$((h / p))" continue 2 fi done break done fi echo "$w:$h" } #-----------------------------------------------------------------------------------------------; # переводим размеры файла в человеко-читаемую строку, добавляем пробел и отбрасываем нули из дробной части function BKM { numfmt --to=iec --format="%.2f" --suffix="B" "$(tee)" | sed -r 's|,{,1}0{,2}([BKM])| \1|'; } #-----------------------------------------------------------------------------------------------; # дописываем размеры файла и изображения, вычисляем соотношение сторон function append_sizes { file_size="$1;$(stat --printf="%s" "$1" | BKM)" case "${1##*.}" in "jxl" | "bmp" | "gif" | "ico" | "jpg" | "png" | "svg" | "webp") size="$(exiftool -imagesize "$1" | tr -d ' ' | sed -r 's|ImageSize:\|\.0{1,2}||g')" if [ -z "$size" ] && [ "${1##*.}" == "svg" ]; then size="$(exiftool -SVG:ViewBox "$1" | tr ' ' 'x' | sed 's|ViewxBox*:x0x0x||g')" fi echo "$file_size / $size / $(aspect_ratio "$size")" ;; *) echo "$file_size" ;; esac } #-----------------------------------------------------------------------------------------------; # получаем список файлов и сохраняем этот список в файл function repo_list { dir="${1#*:}" && red="\e[91m" && green="\e[92m" && norm="\e[0m" # соответствующая строка для вывода сообщений по ходу выполнения функции num="${1%:*}" && pre="\e[${num}A${dir}: " && aft="\e[K\e[${num}B\r" cd "./$dir" &>/dev/null || { printf "${pre}${red}%s${norm}${aft}" "Не найден каталог." && return } printf "${pre}%s${aft}" "Создание списка файлов." # запуск параллельной обработки файлов репозитория и сохранение результатов в массив readarray -t repo_list < <(find . -type f -not -name '*.log' -not -path "*/.*" \ -printf 'append_sizes "%p"\0' | xargs -n1 -0 -P0 bash -c) # вывод строк массива, сортировка и сохранение в файл printf '%s\n' "${repo_list[@]}" | LC_COLLATE=C sort -r >"$basedir/repo_list/$dir.txt" printf "${pre}${green}%s${norm}${aft}" "Выполнено." } #-----------------------------------------------------------------------------------------------; export -f repo_list append_sizes BKM aspect_ratio export basedir="$PWD" cd .. # выход из репозитория # поиск всех каталогов на одном уровне с текущим, кроме папки ".idea", сортировка и добавление порядковых номеров для строк readarray -t folders < <(find . -mindepth 1 -maxdepth 1 -type d -not -name ".idea" -printf '%f\n' | sort -r | grep -n '\S') # смещение курсора вниз на соответствующее количество строк printf '%s\n' "${folders[@]#*:}" | sort # вывод строк массива и параллельный запуск функции для каждого каталога printf 'repo_list "%s"\0' "${folders[@]}" | xargs -n1 -0 -P0 bash -c #-----------------------------------------------------------------------------------------------; # замер продолжительности выполнения в миллисекундах, пересчёт в минуты, секунды и миллисекунды tms="$(($(date '+%s%3N') - time_ms))" && min="$((tms / 1000 / 60))" && sec="$((tms / 1000 % 60))" ms="$((tms % 1000))" && printf 'Общее время выполнения: %02d:%02d.%03d мс.\n' "$min" "$sec" "$ms"