Issue
I have a large number of images in the following format -
randomname_08042020_1837_sometext_somemoretext.jpg
randomname_17012022_1650_sometext_somemoretext.th.jpg
randomname_08042020_1837_sometext_somemoretext.th.jpg
randomname_17012022_1658_sometext_somemoretext.jpg
randomname_09042020_0009_sometext_somemoretext.jpg
randomname_17012022_1658_sometext_somemoretext.th.jpg
randomname_09042020_0009_sometext_somemoretext.th.jpg
randomname_17012022_1711_sometext_somemoretext.jpg
randomname_15062020_1736_sometext_somemoretext.jpg
randomname_17012022_1711_sometext_somemoretext.th.jpg
randomname_15062020_1736_sometext_somemoretext.th.jpg
randomname_17012022_1719_sometext_somemoretext.jpg
randomname_09052020_1812_sometext_somemoretext.jpg
randomname_17012022_1719_sometext_somemoretext.th.jpg
randomname_09052020_1812_sometext_somemoretext.th.jpg
randomname_17012022_1730_sometext_somemoretext.jpg
randomname_09052020_1838_sometext_somemoretext.jpg
randomname_17012022_1730_sometext_somemoretext.th.jpg
randomname_09052020_1838_sometext_somemoretext.th.jpg
randomname_17092021_2340_sometext_somemoretext.jpg
I require a script to sort them into yyyy/mm/dd folders (and create the folders) based on the date in the filename, which is located after the first underscore in a ddmmyyyy format.
I've tried various suggestions from other answers using sed but none of them work. randomname, sometext and somemoretext are not constant length variables
Edit - to add what I have tried so far.
Someone came up with a solution based on a similar question with a different date format in the filename YYYYMMDDHHMMSS and was given this code as an answer -
#!/bin/bash
cd /home/user/files
for file in *.msg; do
date=$(printf "$file" | sed -nE 's/.*_([0-9]{4})([01][0-9])([0-3][0-9])[0-2][0-9][0-6][0-9][0-6][0-9]_.*/\1\/\2\/\3/p')
if [ -n "$date" ]; then
mkdir -p "$date" && mv "$file" "$date"
fi
done
Which I attempted to tweak by moving the regex capture elements around to suit my file date format DDMMYYY -
#!/bin/bash
cd /opt/large-out
for file in *.jpg; do
date=$(printf "$file" | sed -nE 's/.*_([01][0-9])([0-9]{4})([0-3][0-9])([0-9]{4})_.*/\3\/\2\/\1/p')
if [ -n "$date" ]; then
mkdir -p "$date" && mv "$file" "$date"
fi
done
But this did not work, there was no movement of files or any error, just nothing happened.
Solution
With bash
:
for f in *.jpg; do
if [[ "$f" =~ _([0-9]{2})([0-9]{2})([0-9]{4})_ ]]; then
dir="${BASH_REMATCH[3]}/${BASH_REMATCH[2]}/${BASH_REMATCH[1]}"
echo mkdir -p "$dir"
echo mv "$f" "$dir";
fi
done
Remove both echo
s if output looks fine.
Answered By - Cyrus Answer Checked By - Marilyn (WPSolving Volunteer)