Obsah
Přesun FOTO RAW (CR2/CR3) jinam, do stejné struktury SKRIPT BASH Synology PUTTY
požadavek:
přesunout RAW fotografie z SSD na HDD (jiný volume, stejná struktura)
nejnovější, snad už full ok
bash skript, který: prohledá adresář fotek, najde raw (CR2, CR3), zjistí zda k nim existuje identicky pojmenovaný JPG, JPEG, nebo HEIC a pokud ano, tak vytvoří na jiném volume stejnou strukturu složek a do té tyto RAW soubory přesune (úspora místa na primárním volume)
odpověď
Bash skript, který: - projde adresář s fotkami (rekurzivně), - najde RAW soubory CR2 / CR3, - ověří, zda existuje stejně pojmenovaný JPG / JPEG / HEIC, - pokud ano → vytvoří stejnou strukturu složek na jiném volume, - a přesune tam RAW soubory (šetří místo na primárním volume). kompletní, čistý a bezpečný skript, už včetně ochrany pro: - @eaDir - .dtrash - #snapshot - #recycle - všechny skryté složky (.*) - a jakékoli další systémové adresáře, které by se mohly objevit Skript: - prochází jen roky 2025+ - přesouvá RAWy s JPG normálně - RAWy bez JPG přesouvá, ale přidá _SMAZAT - maže jen prázdné složky, které nejsou systémové ani skryté - vše loguje
Skript je napsaný tak, aby fungoval i na Synology.
#!/bin/bash SOURCE_DIR="/volume1/photo" TARGET_DIR="/volume2/VOL2-RAW-photo" LOG_FILE="/volume1/ZPRAVY_Systemu/presun-raw-do-vol2/raw_log.txt" RAW_EXT="raw cr2 cr3 afphoto" JPG_EXT="jpg jpeg" echo "===== LOG START $(date) =====" > "$LOG_FILE" # Funkce pro nalezení odpovídajícího JPG has_matching_jpg() { local raw_file="$1" local base="${raw_file%.*}" for ext in $JPG_EXT; do for candidate in "${base}.${ext}" "${base}.${ext^^}" "${base}.${ext^}" "${base}.${ext,,}"; do if [ -f "$candidate" ]; then return 0 fi done done return 1 } # Procházíme jen roky 2025+ find "$SOURCE_DIR"/20[2-9][5-9]* \ -type d \( -name "@eaDir" -o -name ".dtrash" \) -prune -o \ -type f -print0 | while IFS= read -r -d '' file; do ext="${file##*.}" ext_lower=$(echo "$ext" | tr 'A-Z' 'a-z') if echo "$RAW_EXT" | grep -qw "$ext_lower"; then echo "Zpracovávám RAW: $file" rel_path="${file#$SOURCE_DIR/}" target_path="$TARGET_DIR/$rel_path" target_dir=$(dirname "$target_path") mkdir -p "$target_dir" if has_matching_jpg "$file"; then # RAW má JPG → přesun beze změny názvu mv "$file" "$target_path" echo "MOVED: $file -> $target_path" >> "$LOG_FILE" else # RAW nemá JPG → přidáme _SMAZAT base=$(basename "$target_path") name="${base%.*}" ext="${base##*.}" new_name="${name}_SMAZAT.${ext}" new_path="${target_dir}/${new_name}" mv "$file" "$new_path" echo "MISSING JPG (MOVED+RENAMED): $file -> $new_path" >> "$LOG_FILE" fi fi done # 🧹 Bezpečné mazání prázdných složek v SOURCE_DIR echo "Mazání prázdných složek v $SOURCE_DIR..." >> "$LOG_FILE" find "$SOURCE_DIR" \ -type d -empty \ ! -name ".*" \ ! -name "@eaDir" \ ! -path "*/@eaDir/*" \ ! -name ".dtrash" \ ! -path "*/.dtrash/*" \ ! -name "#snapshot" \ ! -path "*/#snapshot/*" \ ! -name "#recycle" \ ! -path "*/#recycle/*" \ -print -delete >> "$LOG_FILE" # 🧹 Bezpečné mazání prázdných složek v TARGET_DIR echo "Mazání prázdných složek v $TARGET_DIR..." >> "$LOG_FILE" find "$TARGET_DIR" \ -type d -empty \ ! -name ".*" \ ! -name "@eaDir" \ ! -path "*/@eaDir/*" \ ! -name ".dtrash" \ ! -path "*/.dtrash/*" \ ! -name "#snapshot" \ ! -path "*/#snapshot/*" \ ! -name "#recycle" \ ! -path "*/#recycle/*" \ -print -delete >> "$LOG_FILE" echo "===== LOG END $(date) =====" >> "$LOG_FILE" echo "Hotovo. Log: $LOG_FILE"
🔧 Stačí upravit dvě proměnné: SRC a DST
tento fungoval původní:
#!/bin/bash #POZADOVANO po copilot: #skript, který: projde zadaný adresář a podadresáře, #najde fotky RAW, CR2, CR3 a zjistí, ke kterým je v daném umístění odpovídající verze JPG, JPEG. #následně v zadaném umístění vytvoří identickou strukturu adresářů #a ty RAW, CR2, CR3 které mají odpovídající JPG či JPEG tam přesune a zapíše do logu (i s cestou). #raw, cr2, R3 které nemají odpovídající JPG či JPEG zapíše do logu i s cestou. # SOURCE_DIR="/volume1/photo" TARGET_DIR="/volume2/VOL2-RAW-photo" LOG_FILE="/volume1/ZPRAVY_Systemu/presun-raw-do-vol2/raw_log.txt" RAW_EXT="raw cr2 cr3 afphoto" JPG_EXT="jpg jpeg" echo "===== LOG START $(date) =====" > "$LOG_FILE" # Funkce pro nalezení odpovídajícího JPG has_matching_jpg() { local raw_file="$1" local base="${raw_file%.*}" for ext in $JPG_EXT; do for candidate in "${base}.${ext}" "${base}.${ext^^}" "${base}.${ext^}" "${base}.${ext,,}"; do if [ -f "$candidate" ]; then return 0 fi done done return 1 } # Hlavní smyčka – robustní verze s -print0 find "$SOURCE_DIR" \ -type d \( -name "@eaDir" -o -name ".dtrash" \) -prune -o \ -type f -print0 | while IFS= read -r -d '' file; do ext="${file##*.}" ext_lower=$(echo "$ext" | tr 'A-Z' 'a-z') if echo "$RAW_EXT" | grep -qw "$ext_lower"; then echo "Zpracovávám RAW: $file" if has_matching_jpg "$file"; then rel_path="${file#$SOURCE_DIR/}" target_path="$TARGET_DIR/$rel_path" target_dir=$(dirname "$target_path") mkdir -p "$target_dir" mv "$file" "$target_path" echo "MOVED: $file -> $target_path" >> "$LOG_FILE" else echo "MISSING JPG: $file" >> "$LOG_FILE" fi fi done echo "===== LOG END $(date) =====" >> "$LOG_FILE" echo "Hotovo. Log: $LOG_FILE"
🧠 Jak skript funguje
1) find najde všechny RAW soubory CR2 a CR3, rekurzivně.
2) Pro každý RAW zjistí, zda existuje: - stejné_jméno.jpg - stejné_jméno.jpeg - stejné_jméno.heic
3) Pokud ano: - spočítá relativní cestu vůči zdroji, - vytvoří stejnou strukturu složek v cílovém volume, - přesune RAW soubor.
VARIANTA kdy RAW nemá JPEGa, tedy je asi ke smazání
(běžně mažeu v jpg, rawy jsou zvlášť)
připravím ti rozšířenou verzi skriptu, která: - pokud existuje JPG/JPEG/HEIC → přesune RAW do ARCHIVU RAW -RAW bez JPG se přesune stejně jako ostatní, jen dostane _SMAZAT - zachová stejnou strukturu složek - vše loguje do samostatného logu při každém spuštění Tohle je velmi praktické, protože hned vidíš, které RAWy nemají odpovídající náhled.
#!/bin/bash SOURCE_DIR="/volume1/photo" TARGET_DIR="/volume2/VOL2-RAW-photo" LOG_FILE="/volume1/ZPRAVY_Systemu/presun-raw-do-vol2/raw_log.txt" RAW_EXT="raw cr2 cr3 afphoto" JPG_EXT="jpg jpeg" echo "===== LOG START $(date) =====" > "$LOG_FILE" # Funkce pro nalezení odpovídajícího JPG has_matching_jpg() { local raw_file="$1" local base="${raw_file%.*}" for ext in $JPG_EXT; do for candidate in "${base}.${ext}" "${base}.${ext^^}" "${base}.${ext^}" "${base}.${ext,,}"; do if [ -f "$candidate" ]; then return 0 fi done done return 1 } # Procházíme jen roky 2025+ find "$SOURCE_DIR"/20[2-9][5-9]* \ -type d \( -name "@eaDir" -o -name ".dtrash" \) -prune -o \ -type f -print0 | while IFS= read -r -d '' file; do ext="${file##*.}" ext_lower=$(echo "$ext" | tr 'A-Z' 'a-z') if echo "$RAW_EXT" | grep -qw "$ext_lower"; then echo "Zpracovávám RAW: $file" rel_path="${file#$SOURCE_DIR/}" target_path="$TARGET_DIR/$rel_path" target_dir=$(dirname "$target_path") mkdir -p "$target_dir" if has_matching_jpg "$file"; then # RAW má JPG → přesun beze změny názvu mv "$file" "$target_path" echo "MOVED: $file -> $target_path" >> "$LOG_FILE" else # RAW nemá JPG → přidáme _SMAZAT base=$(basename "$target_path") name="${base%.*}" ext="${base##*.}" new_name="${name}_SMAZAT.${ext}" new_path="${target_dir}/${new_name}" mv "$file" "$new_path" echo "MISSING JPG (MOVED+RENAMED): $file -> $new_path" >> "$LOG_FILE" fi fi done # 🧹 Mazání prázdných složek v SOURCE_DIR echo "Mazání prázdných složek v $SOURCE_DIR..." >> "$LOG_FILE" find "$SOURCE_DIR" \ -type d \( -name "@eaDir" -o -name ".dtrash" \) -prune -o \ -type d -empty -print -delete >> "$LOG_FILE" # 🧹 Mazání prázdných složek v TARGET_DIR echo "Mazání prázdných složek v $TARGET_DIR..." >> "$LOG_FILE" find "$TARGET_DIR" \ -type d \( -name "@eaDir" -o -name ".dtrash" \) -prune -o \ -type d -empty -print -delete >> "$LOG_FILE" echo "===== LOG END $(date) =====" >> "$LOG_FILE" echo "Hotovo. Log: $LOG_FILE"
🧠 Co skript dělá navíc oproti původní verzi - neprochází staré roky → výrazně rychlejší - RAW bez JPG se přesune stejně jako ostatní, jen dostane _SMAZAT - 🧠 Co skript teď dělá navíc Po přesunech: ✔ smaže prázdné složky v SOURCE_DIR → zůstane tam jen to, co obsahuje JPG nebo jiné soubory ✔ smaže prázdné složky v TARGET_DIR → pokud se vytvořila nějaká prázdná struktura (např. RAWy byly _SMAZAT a přesunuly se jinam), nebude tam bordel ✔ vše loguje → vidíš přesně, které složky byly odstraněny
