#!/bin/bash echo "Перекодирование изображений из каталога 'wallpapers' в каталог 'wallpapers2'." #-----------------------------------------------------------------------------------------------; 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')" # текущее время в миллисекундах #-----------------------------------------------------------------------------------------------; # файл-отчёт о завершении работы функции, удаление старого файла export logfile="$PWD/logs/wallpapers.log" && rm -f "$logfile" #-----------------------------------------------------------------------------------------------; # создание структуры каталогов "wallpapers2", создание вспомогательных файлов #-----------------------------------------------------------------------------------------------; # переход в каталог-источник cd "../wallpapers" || exit 1 # создание каталога-преемника, если его нет mkdir -p "../wallpapers2" # удаление файлов и папок, кроме папки ".git" find "../wallpapers2" -mindepth 1 -maxdepth 1 -type d,f -not -name ".git" -exec rm -rf {} \; # создание каталогов "full-size" и "preview" find . -mindepth 1 -maxdepth 1 -type d -not -name ".git" \ -printf "%f/full-size\0%f/preview\0" | xargs -I{} -n1 -0 -P0 bash -c 'mkdir -p "../wallpapers2/{}"' # копирование файлов ".md" и удаление суффиксов, если они есть find . -type f -name "*.md*" \ -printf "cp -f %h/%f ../wallpapers2/%h/@%f\n" | sed -r 's|@(.*?\.md).*$|\1|' | xargs -n1 -0 -P0 bash -c # создание файла ".gitattributes" attr+=("*.jpg linguist-language=JPG") attr+=("*.png linguist-language=PNG") attr+=("*.webp linguist-language=WEBP") printf '%s\n' "${attr[@]}" >"../wallpapers2/.gitattributes" #-----------------------------------------------------------------------------------------------; # перекодирование изображений из каталога "wallpapers" в каталог "wallpapers2" #-----------------------------------------------------------------------------------------------; # обработка изображений function graphics_magick { dir="$2" && file="${3%.*}" folder_fs="../wallpapers2/${dir//original/full-size}" folder_pv="../wallpapers2/${dir//original/preview}" { # создание временного файла case "${3##*.}" in "bmp") tmp="bmp" && ext="png" && cp "$dir/$3" "$folder_fs/$file.tmp.$tmp" ;; "jpg") tmp="jpg" && ext="jpg" && cp "$dir/$3" "$folder_fs/$file.tmp.$tmp" ;; "jxl") tmp="jxl" && ext="jpg" && cp "$dir/$3" "$folder_fs/$file.tmp.$tmp" ;; "png") tmp="png" && ext="png" && cp "$dir/$3" "$folder_fs/$file.tmp.$tmp" ;; "svg") tmp="png" && ext="png" && rsvg-convert "$dir/$3" -o "$folder_fs/$file.tmp.$tmp" ;; *) return ;; # пять типов изображений esac # полноразмерное изображение — удаление лишних профилей, качество 90% gm convert "$folder_fs/$file.tmp.$tmp" -strip -quality 90% "$folder_fs/$file.$ext" # уменьшенное изображение — 512 пикселей по горизонтали, удаление лишних профилей, качество 90% gm convert "$folder_fs/$file.tmp.$tmp" -strip -resize 512!x\> -quality 90% "$folder_pv/$file.webp" # удаление временного файла rm "$folder_fs/$file.tmp.$tmp" } &>>/dev/null # отчёт о завершении выполнения функции echo "$dir/$3" >>"$logfile" # соответствующая строка для текущего каталога pre="\e[${1}A" && aft="\e[K\e[${1}B\r" # массив общего количества файлов и цвета для его отображения read -ra array <<<"$count" && green="\e[92m" && norm="\e[0m" # текущее значение и общее значение для текущего каталога и для всех каталогов current_dir="$(grep -c "^$dir" "$logfile")" && total_dir="${array[$1]}" current_all="$(grep -c "." "$logfile")" && total_all="${array[0]}" [ "$current_dir" == "$total_dir" ] && file="${dir}" || file="${dir}/$3" [ "$current_dir" == "$total_dir" ] && c1="$green" || c1="$norm" [ "$current_all" == "$total_all" ] && c2="$green" || c2="$norm" printf "${pre}Обработано: [${c1}%d/%d${norm}] %s${aft}" "$current_dir" "$total_dir" "$file" printf "Всего обработано файлов: [${c2}%d/%d${norm}]\r" "$current_all" "$total_all" } export -f graphics_magick # поиск всех каталогов "original", сортировка и добавление порядковых номеров для строк readarray -t folders < <(find . -type d -path "*original*" -printf '%p\n' | sort -r | grep -n '\S') # строка-массив общего количества файлов в каждом каталоге *original* для дочерних процессов export count && count="$(printf 'find %s -type f | wc -l\0' "${folders[@]#*:}" | xargs -n1 -0 bash -c | tr '\n' ' ')" # общее количество файлов во всех каталогах *original* count="$(echo "$count" | numsum -r) $count" # смещение курсора вниз на соответствующее количество строк printf 'Каталог: %s\n' "${folders[@]#*:}" | sort # строка замены путей для каталогов "original" на такие же с порядковыми номерами replace="sed $(printf "%s\n" "${folders[@]}" | sed -E "s/(.+):(.+)/-e 's|\"\2\"|\"\1\" \"\2\"|g'/" | tr '\n' ' ')" # поиск всех файлов в каталогах "original", добавление порядковых номеров и параллельный запуск функции для каждого find . -type f -path "*original*" -printf 'graphics_magick "%h" "%f"\0' | eval "$replace" | xargs -n1 -0 -P0 bash -c #-----------------------------------------------------------------------------------------------; # замер продолжительности выполнения в миллисекундах, пересчёт в минуты, секунды и миллисекунды tms="$(($(date '+%s%3N') - time_ms))" && min="$((tms / 1000 / 60))" && sec="$((tms / 1000 % 60))" ms="$((tms % 1000))" && printf '\nОбщее время выполнения: %02d:%02d.%03d мс.\n' "$min" "$sec" "$ms"