Sort/move files into folders and rename existing files.

Hello everyone!
Im having a few problems with my file moving script.
Im trying to move files into folders based on the filenames and if a file already exists rename that file.

The files consists of three sets of different filenames. They will be moved/sorted into the folder structure below. The Source and Destination path will always be static.

OBJECTS/2018/1803/180313/DNG
OBJECTS/2018/1803/180313/TIFF
OBJECTS/2018/1803/180313/JPEG

Example filenames:

15512-1.dng
15512-1.tif
15512-1.jpg

180313-1.dng
180313-1.tif
180313-1.jpg

2002005-1.dng
2002005-1.tif
2002005-1.jpg

The code below kind of works but there must be a better way to loop through the files than to use two �While do� statements.
Another thing I'm having trouble with is if a file already exists, I would like to rename or append something to that existing file. I tried with --backup but all I get is illegal option, most likely due to me testing this on MacOS.

My intension is to run this on my Synology server as an automated task every evening.
When i try to execute the script on the server it complains about the Source path, maybe not correctly formatted?
find: `"/volume1/Archive/IMAGES/UPLOAD/TIFF/"': No such file or directory

#!/bin/bash
SRC1=/volume1/Archive/IMAGES/UPLOAD/JPEG/
SRC2=/volume1/Archive/IMAGES/UPLOAD/TIFF/
DST=/volume1/Archive/IMAGES/OBJECTS/
{
export LC_CTYPE=UTF-8
while IFS= read -r -d $'\\0' f1
do
    n=${f1##*/}
    [[ $n =~ ^(([0-9]{2})([0-9]{1,2})[0-9]{2,3})[^0-9] ]] || continue	 #5,6 & 7-digits (yymkk) (yymmkk) (yymmkkk)
    p=${BASH_REMATCH[1]}
    y=${BASH_REMATCH[2]}
    m=${BASH_REMATCH[3]}
    m='0'$m
    m=${m: -2}
	
	jpg=${DST}/'20'${y}/${y}${m}/${p}/JPEG
	[[ -d $jpg ]] || mkdir -p \"$jpg\" || continue
    

	cp -v -n \"$f1\" \"$jpg\"
	
	
done < <(find \"$SRC1\" -type f -iname '*.jpg' -print0)

# TIFF files
while IFS= read -r -d $'\\0' f2
do
    n=${f2##*/}
    [[ $n =~ ^(([0-9]{2})([0-9]{1,2})[0-9]{2,3})[^0-9] ]] || continue	 #5,6 & 7-digits (yymkk) (yymmkk) (yymmkkk)
    p=${BASH_REMATCH[1]}
    y=${BASH_REMATCH[2]}
    m=${BASH_REMATCH[3]}
    m='0'$m
    m=${m: -2}
	
	tif=${DST}/'20'${y}/${y}${m}/${p}/TIFF
	[[ -d $tif ]] || mkdir -p \"$tif\" || continue
    
	cp -v -n \"$f2\" \"$tif\"
	
	
done < <(find \"$SRC2\" -type f -iname '*.tif' -print0)


} 2>&1
exit 0

Hint:

find /path/to/search \( -iname '*.jpg' -o -iname '*.tif' \)
1 Like

Hmmm - I don't see /volume1/Archive/IMAGES/UPLOAD/DNG/ referenced anywhere in your script - that error msg can't come from that script. Does the DNG directory exist in the path?

1 Like

Sorry, that was a typo. I used the DNG directory befor, but now only the TIFF and JPEG, still get the same error and they do exist.

--- Post updated at 14:24 ---

Thanks, i'm pretty new to this, not quite sure i get the hint.
so this would find all files with .jpg and .tif but only from one path. How can i search both SRC1 and SRC2.
(find \"$SRC1\" -type f -iname '*.tif' -o -iname '*.jpg' -print0)

Drop the escaped double quotes in find 's "starting point". find does allow multiple "starting points", BTW.

1 Like

Great, thanks! now i don't get any errors, but also the script is not working. Nothing is happening, no error codes.
Obviously i must be missing something.

#!/bin/bash
SRC="/volume1/Archive/IMAGES/UPLOAD/TEST1"
DST="/volume1/Archive/IMAGES/UPLOAD/TEST2"
{
export LC_CTYPE=UTF-8

while IFS= read -r -d $'\\0' f1
do
    n=${f1##*/}
    [[ $n =~ ^(([0-9]{2})([0-9]{1,2})[0-9]{2,3})[^0-9] ]] || continue	 #5,6 & 7-digits (yymkk) (yymmkk) (yymmkkk)
    p=${BASH_REMATCH[1]}
    y=${BASH_REMATCH[2]}
    m=${BASH_REMATCH[3]}
    m='0'$m
    m=${m: -2}
	
	dng=${DST}/'20'${y}/${y}${m}/${p}/DNG
	[[ -d $dng ]] || mkdir -p \"$dng\" || continue
    
	mv -v -b \"$f1\" \"$dng\"

done < <(find $SRC -type f -iname '*.dng' -print0)


} 2>&1
exit 0

Again: too many escapes. Drop one of the two back slashes in the read delimiter's -d definition. Same for ALL the escaped double quotes around file and directory names downstream.

Sure your sophisticated regex to analyse $n works reliably? I'd prefer to determine the number length upfront, and then dissect $n .
You might want to provide a default valuein case $DST is undefined, to avoid creating directories in root.

1 Like

Thanks so much for pointing that out, now it works beautifully :slight_smile:
So far it has been reliable, but i will look into changing it your suggestion.
Thanks again!