Move files from subfolders
I've been beating my head against this for a while, but I'm really not a good script writer. Apologies...
I'm running Ubuntu/gnome 18.10, and have a large set of pictures exported from my wifey's mac. The directory structure is:
year1
(login dir name with spaces) - Month
Image names
year2
...
as in:
2013
May 4, 2013
Image1.jpg
Image2.jpg
May 5, 2013
Image 1.jpg
Image 3.jpg
June 22, 2013
What I would like, is:
2013
January
All the "january" images...
February
All the...
I can create the directories easily enough mkdir {January..December}
suffices. But I cannot figure out how to walk the ugly directory tree (exported from Mac), move the images, and then delete the ugly directory.
command-line bash
add a comment |
I've been beating my head against this for a while, but I'm really not a good script writer. Apologies...
I'm running Ubuntu/gnome 18.10, and have a large set of pictures exported from my wifey's mac. The directory structure is:
year1
(login dir name with spaces) - Month
Image names
year2
...
as in:
2013
May 4, 2013
Image1.jpg
Image2.jpg
May 5, 2013
Image 1.jpg
Image 3.jpg
June 22, 2013
What I would like, is:
2013
January
All the "january" images...
February
All the...
I can create the directories easily enough mkdir {January..December}
suffices. But I cannot figure out how to walk the ugly directory tree (exported from Mac), move the images, and then delete the ugly directory.
command-line bash
I'd want to rename the images first, probably adding the full date, otherwise it looks like they'll overwrite each other if moved to a common directory. If the file's dates match their folder's dates that might be easier than using the file's path..
– Xen2050
Jan 16 at 23:14
@Xen2050 Thanks - the file naming has changed over the years as cameras were bought and destroyed... but I think I have a fairly elegant solution. It unfortunately does not advance my knowledge of scripting...exiftool '-FileName<DateTimeOriginal' -d %Y/%m-%B/%f%%-c.%%e . -r
-> it's almost perfect, except for some .mov files which do not have exif data
– Charles Green
Jan 17 at 0:28
add a comment |
I've been beating my head against this for a while, but I'm really not a good script writer. Apologies...
I'm running Ubuntu/gnome 18.10, and have a large set of pictures exported from my wifey's mac. The directory structure is:
year1
(login dir name with spaces) - Month
Image names
year2
...
as in:
2013
May 4, 2013
Image1.jpg
Image2.jpg
May 5, 2013
Image 1.jpg
Image 3.jpg
June 22, 2013
What I would like, is:
2013
January
All the "january" images...
February
All the...
I can create the directories easily enough mkdir {January..December}
suffices. But I cannot figure out how to walk the ugly directory tree (exported from Mac), move the images, and then delete the ugly directory.
command-line bash
I've been beating my head against this for a while, but I'm really not a good script writer. Apologies...
I'm running Ubuntu/gnome 18.10, and have a large set of pictures exported from my wifey's mac. The directory structure is:
year1
(login dir name with spaces) - Month
Image names
year2
...
as in:
2013
May 4, 2013
Image1.jpg
Image2.jpg
May 5, 2013
Image 1.jpg
Image 3.jpg
June 22, 2013
What I would like, is:
2013
January
All the "january" images...
February
All the...
I can create the directories easily enough mkdir {January..December}
suffices. But I cannot figure out how to walk the ugly directory tree (exported from Mac), move the images, and then delete the ugly directory.
command-line bash
command-line bash
edited Jan 17 at 11:08
pa4080
14.3k52669
14.3k52669
asked Jan 16 at 17:59
Charles GreenCharles Green
13.7k73858
13.7k73858
I'd want to rename the images first, probably adding the full date, otherwise it looks like they'll overwrite each other if moved to a common directory. If the file's dates match their folder's dates that might be easier than using the file's path..
– Xen2050
Jan 16 at 23:14
@Xen2050 Thanks - the file naming has changed over the years as cameras were bought and destroyed... but I think I have a fairly elegant solution. It unfortunately does not advance my knowledge of scripting...exiftool '-FileName<DateTimeOriginal' -d %Y/%m-%B/%f%%-c.%%e . -r
-> it's almost perfect, except for some .mov files which do not have exif data
– Charles Green
Jan 17 at 0:28
add a comment |
I'd want to rename the images first, probably adding the full date, otherwise it looks like they'll overwrite each other if moved to a common directory. If the file's dates match their folder's dates that might be easier than using the file's path..
– Xen2050
Jan 16 at 23:14
@Xen2050 Thanks - the file naming has changed over the years as cameras were bought and destroyed... but I think I have a fairly elegant solution. It unfortunately does not advance my knowledge of scripting...exiftool '-FileName<DateTimeOriginal' -d %Y/%m-%B/%f%%-c.%%e . -r
-> it's almost perfect, except for some .mov files which do not have exif data
– Charles Green
Jan 17 at 0:28
I'd want to rename the images first, probably adding the full date, otherwise it looks like they'll overwrite each other if moved to a common directory. If the file's dates match their folder's dates that might be easier than using the file's path..
– Xen2050
Jan 16 at 23:14
I'd want to rename the images first, probably adding the full date, otherwise it looks like they'll overwrite each other if moved to a common directory. If the file's dates match their folder's dates that might be easier than using the file's path..
– Xen2050
Jan 16 at 23:14
@Xen2050 Thanks - the file naming has changed over the years as cameras were bought and destroyed... but I think I have a fairly elegant solution. It unfortunately does not advance my knowledge of scripting...
exiftool '-FileName<DateTimeOriginal' -d %Y/%m-%B/%f%%-c.%%e . -r
-> it's almost perfect, except for some .mov files which do not have exif data– Charles Green
Jan 17 at 0:28
@Xen2050 Thanks - the file naming has changed over the years as cameras were bought and destroyed... but I think I have a fairly elegant solution. It unfortunately does not advance my knowledge of scripting...
exiftool '-FileName<DateTimeOriginal' -d %Y/%m-%B/%f%%-c.%%e . -r
-> it's almost perfect, except for some .mov files which do not have exif data– Charles Green
Jan 17 at 0:28
add a comment |
3 Answers
3
active
oldest
votes
Here is such script:
#!/bin/bash
# The destination where the new directory structure will be created
DEST="/tmp/new-order-pictures/"
MONTHS=('Jan' 'Feb' 'Mar' 'Apr' 'May' 'Jun' 'Jul' 'Aug' 'Sep' 'Oct' 'Nov' 'Dec')
# Walk through the first level directories, located in the current directory and go inside
for year in */
do
cd "$year"
# Walk through the months of the year
for month in "${MONTHS[@]}"
do
# Walk through the second level directories
for dir in */
do
# If we have coincidence between the name of the directory and the month
# go inside, make a new destination directory; ignore character cases^^
if [[ ${dir^^} =~ ${month^^} ]]
then
cd "$dir"
dest="${DEST}${year}${month}"
mkdir -p "$dest"
find . -type f | while IFS= read -r item
do
# Copy the files to the new destination and
# add the file's md5sum to its name to prevent files lose
filename=$(basename -- "$item")
extn="${filename##*.}"
name="${filename%.*}"
cp "$item" "${dest}/${name}-$(md5sum "$item" | cut -f1 -d' ').${extn}"
done
cd ..
fi
done
done
cd ..
done
The script should be executed in the first level directory where your images are located. You should tweak the destination directory - DEST="/tmp/new-order-pictures/"
. This version of the script relies that all files are in directories that contain the name of a month in one way or another. Example of usage:
user@host:~/Pictures$ tree .
.
├── 2013
│ ├── January 17, 2013
│ │ ├── Image1.jpg
│ │ └── Image 3.jpg
│ ├── January 24, 2013
│ │ └── Image2.jpg
│ ├── January 25, 2013
│ │ └── Image 3.jpg
│ ├── June 22, 2013
│ │ └── image1.jpg
│ ├── May 4, 2013
│ │ └── Image1.jpg
│ └── May 5, 2013
│ ├── Image1.jpg
│ └── Image 2.jpg
└── 2014
├── January 17, 2014
│ ├── Image1.jpg
│ └── Image 3.jpg
├── January 24, 2014
│ └── Image2.jpg
├── January 25, 2014
│ └── Image 3.jpg
└── May 5
├── Image1.jpg
└── Image 2.jpg
12 directories, 14 files
user@host:~/Pictures$ order.sh
user@host:~/Pictures$ tree /tmp/new-order-pictures/
/tmp/new-order-pictures/
├── 2013
│ ├── Jan
│ │ ├── Image1-7b71d9fdfe5b15a2d1a4968c195f93ae.jpg
│ │ ├── Image2-cbf4d36ff84e7ec24c05f8181236e6b8.jpg
│ │ ├── Image 3-0bca5188fd3f3eb470533fdaf0630633.jpg
│ │ └── Image 3-6a83880cae1aa57e19a7c45de7759e68.jpg
│ ├── Jun
│ │ └── image1-adb3bf995f1a25d008f758a7266d7be5.jpg
│ └── May
│ ├── Image1-511d541b35fcb38af8ada18d7961268c.jpg
│ ├── Image1-a66c5863e6986605cb2ca6d622ae72a0.jpg
│ └── Image 2-c34ffc32ce5d3901e1ad89b9fd15a877.jpg
└── 2014
├── Jan
│ ├── Image1-7b71d9fdfe5b15a2d1a4968c195f93ae.jpg
│ ├── Image2-cbf4d36ff84e7ec24c05f8181236e6b8.jpg
│ ├── Image 3-0bca5188fd3f3eb470533fdaf0630633.jpg
│ └── Image 3-6a83880cae1aa57e19a7c45de7759e68.jpg
└── May
├── Image1-511d541b35fcb38af8ada18d7961268c.jpg
└── Image 2-c34ffc32ce5d3901e1ad89b9fd15a877.jpg
7 directories, 14 files
In my case the script is named order.sh
and it is located in ~/bin
, thus I can use it as shell command. In the example you can see the directory structure is changed but the number of files is 14 in both structures.
Here is another version of the script that use mv
instead of cp
and will deal also with the files which are not in directories that contain the name of a month. Before running this script it is a good idea to create a backup copy of the original directory structure.
#!/bin/bash
# The destination where the new directory structure will be created
DEST="/tmp/new-order-pictures/"
MONTHS=('Jan' 'Feb' 'Mar' 'Apr' 'May' 'Jun' 'Jul' 'Aug' 'Sep' 'Oct' 'Nov' 'Dec')
# Walk through the first level directories, located in the current directory and go inside
for year in */
do
cd "$year"
# Walk through the months of the year
for month in "${MONTHS[@]}"
do
# Walk through the second level directories
for dir in */
do
# If we have coincidence between the name of the directory and the month
# go inside, make a new destination directory; ignore character cases^^
if [[ ${dir^^} =~ ${month^^} ]]
then
cd "$dir"
dest="${DEST}${year}${month}"
mkdir -p "$dest"
while IFS= read -r item
do
# Copy the files to the new destination and
# add the file's md5sum to its name to prevent files lose
filename=$(basename -- "$item")
extn="${filename##*.}"
name="${filename%.*}"
mv "$item" "${dest}/${name}-$(md5sum "$item" | cut -f1 -d' ').${extn}"
done < <(find . -type f)
cd ..
fi
done
done
# Dial with the rest of the files for that $year
dest="${DEST}${year}other"
while IFS= read -r item
do
mkdir -p "$dest"
filename=$(basename -- "$item")
extn="${filename##*.}"
name="${filename%.*}"
mv "$item" "${dest}/${name}-$(md5sum "$item" | cut -f1 -d' ').${extn}"
done < <(find . -type f)
cd ..
done
Example of usage:
user@host:~/Pictures$ tree .
.
├── 2013
│ ├── January 17, 2013
│ │ ├── Image1.jpg
│ │ ├── Image 3.jpg
│ │ └── video 7.mpg
│ ├── January 25, 2013
│ │ └── Image 3.jpg
│ ├── June 22, 2013
│ │ └── image1.jpg
│ └── May 5, 2013
│ ├── Image1.jpg
│ └── Image 2.jpg
└── 2014
├── Apr 7
│ ├── Image1.jpg
│ └── Image 2.jpg
├── Image 2.jpg
├── January 11, 2014
│ ├── Image1.jpg
│ └── Image 3.jpg
├── some other name
│ └── some other name file inside.jpg
├── some other name file inside.jpg
└── video 1.avi
9 directories, 15 files
user@host:~/Pictures$ order.sh
user@host:~/Pictures$ tree /tmp/new-order-pictures/
/tmp/new-order-pictures/
├── 2013
│ ├── Jan
│ │ ├── Image1-7b71d9fdfe5b15a2d1a4968c195f93ae.jpg
│ │ ├── Image 3-0bca5188fd3f3eb470533fdaf0630633.jpg
│ │ ├── Image 3-6a83880cae1aa57e19a7c45de7759e68.jpg
│ │ └── video 7-86764d9565469adfb22c8ef4f0b9c04f.mpg
│ ├── Jun
│ │ └── image1-adb3bf995f1a25d008f758a7266d7be5.jpg
│ └── May
│ ├── Image1-511d541b35fcb38af8ada18d7961268c.jpg
│ └── Image 2-c34ffc32ce5d3901e1ad89b9fd15a877.jpg
└── 2014
├── Apr
│ ├── Image1-3c19da25e0e56ef0fc752a9e4f75b190.jpg
│ └── Image 2-dcc35e86de393a014ac62e8c4390c7e6.jpg
├── Jan
│ ├── Image1-ae34289b0bc5258f286165745ff3c258.jpg
│ └── Image 3-1724adf2dfcc1d4a0dc50cb38ad2c510.jpg
└── other
├── Image 2-eff5208f7eee6a536e48f9982b918dfb.jpg
├── some other name file inside-7d0a68e0b4e9cc3928744cb83f4d1136.jpg
├── some other name file inside-c2dd637e94a9025c3e1004d66f59539c.jpg
└── video 1-c277d93a2427bedf3f0b8ae07427edb9.avi
8 directories, 15 files
After that you can go inside the destination directory and use the rename
command within for
loop to deal with the long names:
# For each directory on the second level
for dir in */*
do
cd "$dir"
rename 's/^.*(.[0-9a-zA-Z]+)$/our $i; sprintf("Image-%03d$1", 1+$i++)/e' *
cd ..
cd ..
done
Example:
user@host:~/Pictures$ cd /tmp/new-order-pictures/
user@host:/tmp/new-order-pictures$ for dir in */*; do cd "$dir"; rename 's/^.*(.[0-9a-zA-Z]+)$/our $i; sprintf("Image-%03d$1", 1+$i++)/e' *; cd ..; cd ..; done
user@host:/tmp/new-order-pictures$ tree .
.
├── 2013
│ ├── Jan
│ │ ├── Image-001.jpg
│ │ ├── Image-002.jpg
│ │ ├── Image-003.jpg
│ │ └── Image-004.mpg
│ ├── Jun
│ │ └── Image-001.jpg
│ └── May
│ ├── Image-001.jpg
│ └── Image-002.jpg
└── 2014
├── Apr
│ ├── Image-001.jpg
│ └── Image-002.jpg
├── Jan
│ ├── Image-001.jpg
│ └── Image-002.jpg
└── other
├── Image-001.jpg
├── Image-002.jpg
├── Image-003.jpg
└── Image-004.avi
8 directories, 15 files
Or you can change (.[0-9a-zA-Z]+)
with (.jpg)
, then on next iteration with (.mpg)
(respectively Image-
with Video-
), etc. References about this usage of rename
:
How to rename multiple files sequentially from command line?
Renaming hundreds of files at once for proper sorting
Thanks! I think this is really close to what I asked for, and I'll have to scour the web looking for shell expansions et al...
– Charles Green
Jan 17 at 15:05
Hi, @CharlesGreen, I"ve updated the answer with few more ideas. Sorry for the long answer and the lack of explanations inside... if you need clarifications about some parts, please ping me :)
– pa4080
Jan 17 at 18:19
No problem at all - I really am looking to use this more as a reason to learn some shell scripting. I did in fact find a single line command which does exactly what I need!
– Charles Green
Jan 17 at 18:22
@CharlesGreen: Nice! It will be worth to write an answer.
– pa4080
Jan 17 at 18:34
I can certainly share the command, and will add it later. But your command answered a deeper question in prompting me to learn more about scripting
– Charles Green
Jan 17 at 18:59
|
show 1 more comment
There is an application which can move and rename the files in a single command line - exiftool
sudo apt install libimage-exiftool-perl
In my case, the specific command line used was
exiftool '-FileName<DateTimeOriginal' -d <path-to-output-dir>/%Y/%m-%B/%Y%m%d_%H%M%S%%-c.%%e . -r
or
exiftool '-FileName<CreateDate' -d <path-to-output-dir>/%Y/%m-%B/%Y%m%d_%H%M%S%%-c.%%e . -r
depending upon which tag is present in the images. If the requested tag is not present, the application throws a warning and does not move that file, but continues processing. This application also handles multiple images with the same date/time by appending a numeric to the end of the filename.
I did have several images without exif data, and I was able to add exif data to the images with the command
exiftool -createdate='2011:12:04 12:00:00' * -overwrite_original
As an example, I placed some images in a directory ~/aa/test1 and ran the tool, placing the output in ~/aa/test2. The results are below:
chick@dad:~/aa$ tree .
.
├── test1
│ ├── DSC00018.JPG
│ ├── DSC00022.JPG
│ ├── DSC00024.JPG
│ ├── DSC00025.JPG
│ ├── DSC00026.JPG
│ ├── DSC00028.JPG
│ ├── DSC00031.JPG
│ ├── DSC00033.JPG
│ └── Thumbs.db
└── test2
└── 2000
└── 12-December
├── 20001222_185523.JPG
├── 20001222_200726.JPG
├── 20001222_200819.JPG
├── 20001222_201205.JPG
├── 20001222_201223.JPG
├── 20001222_210536.JPG
├── 20001222_211858.JPG
└── 20001222_215950.JPG
Superb! You may accept this answer, because of its simplicity :) Yesterday when I made the last edit on my answer, I realizedrename
can be used in similar way as it is made here, but I do not have time to elaborate.
– pa4080
Jan 18 at 17:33
1
@pa4080 But I still like your answer, because it will cause me to work seeper into scripting...!
– Charles Green
Jan 18 at 17:36
add a comment |
So, I assume you want a step-by-step and simple solution.
First, I would address the problem of Whitespace and comma in the folders.
I would first cd into the year folder and use rename
to first remove Whitespace
rename "s/ //g" *
Similarly, remove comma
rename "s/,//g" *
Now that I have all the folders as desired I would create a month based list using
ls | grep "January" > January.txt
Now make folder "January"
mkdir January
Then loop thru the list using xargs
to copy their contents
cat January.txt | xargs -I {} cp -R {}/. ./January/
add a comment |
Your Answer
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "89"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2faskubuntu.com%2fquestions%2f1110359%2fmove-files-from-subfolders%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
3 Answers
3
active
oldest
votes
3 Answers
3
active
oldest
votes
active
oldest
votes
active
oldest
votes
Here is such script:
#!/bin/bash
# The destination where the new directory structure will be created
DEST="/tmp/new-order-pictures/"
MONTHS=('Jan' 'Feb' 'Mar' 'Apr' 'May' 'Jun' 'Jul' 'Aug' 'Sep' 'Oct' 'Nov' 'Dec')
# Walk through the first level directories, located in the current directory and go inside
for year in */
do
cd "$year"
# Walk through the months of the year
for month in "${MONTHS[@]}"
do
# Walk through the second level directories
for dir in */
do
# If we have coincidence between the name of the directory and the month
# go inside, make a new destination directory; ignore character cases^^
if [[ ${dir^^} =~ ${month^^} ]]
then
cd "$dir"
dest="${DEST}${year}${month}"
mkdir -p "$dest"
find . -type f | while IFS= read -r item
do
# Copy the files to the new destination and
# add the file's md5sum to its name to prevent files lose
filename=$(basename -- "$item")
extn="${filename##*.}"
name="${filename%.*}"
cp "$item" "${dest}/${name}-$(md5sum "$item" | cut -f1 -d' ').${extn}"
done
cd ..
fi
done
done
cd ..
done
The script should be executed in the first level directory where your images are located. You should tweak the destination directory - DEST="/tmp/new-order-pictures/"
. This version of the script relies that all files are in directories that contain the name of a month in one way or another. Example of usage:
user@host:~/Pictures$ tree .
.
├── 2013
│ ├── January 17, 2013
│ │ ├── Image1.jpg
│ │ └── Image 3.jpg
│ ├── January 24, 2013
│ │ └── Image2.jpg
│ ├── January 25, 2013
│ │ └── Image 3.jpg
│ ├── June 22, 2013
│ │ └── image1.jpg
│ ├── May 4, 2013
│ │ └── Image1.jpg
│ └── May 5, 2013
│ ├── Image1.jpg
│ └── Image 2.jpg
└── 2014
├── January 17, 2014
│ ├── Image1.jpg
│ └── Image 3.jpg
├── January 24, 2014
│ └── Image2.jpg
├── January 25, 2014
│ └── Image 3.jpg
└── May 5
├── Image1.jpg
└── Image 2.jpg
12 directories, 14 files
user@host:~/Pictures$ order.sh
user@host:~/Pictures$ tree /tmp/new-order-pictures/
/tmp/new-order-pictures/
├── 2013
│ ├── Jan
│ │ ├── Image1-7b71d9fdfe5b15a2d1a4968c195f93ae.jpg
│ │ ├── Image2-cbf4d36ff84e7ec24c05f8181236e6b8.jpg
│ │ ├── Image 3-0bca5188fd3f3eb470533fdaf0630633.jpg
│ │ └── Image 3-6a83880cae1aa57e19a7c45de7759e68.jpg
│ ├── Jun
│ │ └── image1-adb3bf995f1a25d008f758a7266d7be5.jpg
│ └── May
│ ├── Image1-511d541b35fcb38af8ada18d7961268c.jpg
│ ├── Image1-a66c5863e6986605cb2ca6d622ae72a0.jpg
│ └── Image 2-c34ffc32ce5d3901e1ad89b9fd15a877.jpg
└── 2014
├── Jan
│ ├── Image1-7b71d9fdfe5b15a2d1a4968c195f93ae.jpg
│ ├── Image2-cbf4d36ff84e7ec24c05f8181236e6b8.jpg
│ ├── Image 3-0bca5188fd3f3eb470533fdaf0630633.jpg
│ └── Image 3-6a83880cae1aa57e19a7c45de7759e68.jpg
└── May
├── Image1-511d541b35fcb38af8ada18d7961268c.jpg
└── Image 2-c34ffc32ce5d3901e1ad89b9fd15a877.jpg
7 directories, 14 files
In my case the script is named order.sh
and it is located in ~/bin
, thus I can use it as shell command. In the example you can see the directory structure is changed but the number of files is 14 in both structures.
Here is another version of the script that use mv
instead of cp
and will deal also with the files which are not in directories that contain the name of a month. Before running this script it is a good idea to create a backup copy of the original directory structure.
#!/bin/bash
# The destination where the new directory structure will be created
DEST="/tmp/new-order-pictures/"
MONTHS=('Jan' 'Feb' 'Mar' 'Apr' 'May' 'Jun' 'Jul' 'Aug' 'Sep' 'Oct' 'Nov' 'Dec')
# Walk through the first level directories, located in the current directory and go inside
for year in */
do
cd "$year"
# Walk through the months of the year
for month in "${MONTHS[@]}"
do
# Walk through the second level directories
for dir in */
do
# If we have coincidence between the name of the directory and the month
# go inside, make a new destination directory; ignore character cases^^
if [[ ${dir^^} =~ ${month^^} ]]
then
cd "$dir"
dest="${DEST}${year}${month}"
mkdir -p "$dest"
while IFS= read -r item
do
# Copy the files to the new destination and
# add the file's md5sum to its name to prevent files lose
filename=$(basename -- "$item")
extn="${filename##*.}"
name="${filename%.*}"
mv "$item" "${dest}/${name}-$(md5sum "$item" | cut -f1 -d' ').${extn}"
done < <(find . -type f)
cd ..
fi
done
done
# Dial with the rest of the files for that $year
dest="${DEST}${year}other"
while IFS= read -r item
do
mkdir -p "$dest"
filename=$(basename -- "$item")
extn="${filename##*.}"
name="${filename%.*}"
mv "$item" "${dest}/${name}-$(md5sum "$item" | cut -f1 -d' ').${extn}"
done < <(find . -type f)
cd ..
done
Example of usage:
user@host:~/Pictures$ tree .
.
├── 2013
│ ├── January 17, 2013
│ │ ├── Image1.jpg
│ │ ├── Image 3.jpg
│ │ └── video 7.mpg
│ ├── January 25, 2013
│ │ └── Image 3.jpg
│ ├── June 22, 2013
│ │ └── image1.jpg
│ └── May 5, 2013
│ ├── Image1.jpg
│ └── Image 2.jpg
└── 2014
├── Apr 7
│ ├── Image1.jpg
│ └── Image 2.jpg
├── Image 2.jpg
├── January 11, 2014
│ ├── Image1.jpg
│ └── Image 3.jpg
├── some other name
│ └── some other name file inside.jpg
├── some other name file inside.jpg
└── video 1.avi
9 directories, 15 files
user@host:~/Pictures$ order.sh
user@host:~/Pictures$ tree /tmp/new-order-pictures/
/tmp/new-order-pictures/
├── 2013
│ ├── Jan
│ │ ├── Image1-7b71d9fdfe5b15a2d1a4968c195f93ae.jpg
│ │ ├── Image 3-0bca5188fd3f3eb470533fdaf0630633.jpg
│ │ ├── Image 3-6a83880cae1aa57e19a7c45de7759e68.jpg
│ │ └── video 7-86764d9565469adfb22c8ef4f0b9c04f.mpg
│ ├── Jun
│ │ └── image1-adb3bf995f1a25d008f758a7266d7be5.jpg
│ └── May
│ ├── Image1-511d541b35fcb38af8ada18d7961268c.jpg
│ └── Image 2-c34ffc32ce5d3901e1ad89b9fd15a877.jpg
└── 2014
├── Apr
│ ├── Image1-3c19da25e0e56ef0fc752a9e4f75b190.jpg
│ └── Image 2-dcc35e86de393a014ac62e8c4390c7e6.jpg
├── Jan
│ ├── Image1-ae34289b0bc5258f286165745ff3c258.jpg
│ └── Image 3-1724adf2dfcc1d4a0dc50cb38ad2c510.jpg
└── other
├── Image 2-eff5208f7eee6a536e48f9982b918dfb.jpg
├── some other name file inside-7d0a68e0b4e9cc3928744cb83f4d1136.jpg
├── some other name file inside-c2dd637e94a9025c3e1004d66f59539c.jpg
└── video 1-c277d93a2427bedf3f0b8ae07427edb9.avi
8 directories, 15 files
After that you can go inside the destination directory and use the rename
command within for
loop to deal with the long names:
# For each directory on the second level
for dir in */*
do
cd "$dir"
rename 's/^.*(.[0-9a-zA-Z]+)$/our $i; sprintf("Image-%03d$1", 1+$i++)/e' *
cd ..
cd ..
done
Example:
user@host:~/Pictures$ cd /tmp/new-order-pictures/
user@host:/tmp/new-order-pictures$ for dir in */*; do cd "$dir"; rename 's/^.*(.[0-9a-zA-Z]+)$/our $i; sprintf("Image-%03d$1", 1+$i++)/e' *; cd ..; cd ..; done
user@host:/tmp/new-order-pictures$ tree .
.
├── 2013
│ ├── Jan
│ │ ├── Image-001.jpg
│ │ ├── Image-002.jpg
│ │ ├── Image-003.jpg
│ │ └── Image-004.mpg
│ ├── Jun
│ │ └── Image-001.jpg
│ └── May
│ ├── Image-001.jpg
│ └── Image-002.jpg
└── 2014
├── Apr
│ ├── Image-001.jpg
│ └── Image-002.jpg
├── Jan
│ ├── Image-001.jpg
│ └── Image-002.jpg
└── other
├── Image-001.jpg
├── Image-002.jpg
├── Image-003.jpg
└── Image-004.avi
8 directories, 15 files
Or you can change (.[0-9a-zA-Z]+)
with (.jpg)
, then on next iteration with (.mpg)
(respectively Image-
with Video-
), etc. References about this usage of rename
:
How to rename multiple files sequentially from command line?
Renaming hundreds of files at once for proper sorting
Thanks! I think this is really close to what I asked for, and I'll have to scour the web looking for shell expansions et al...
– Charles Green
Jan 17 at 15:05
Hi, @CharlesGreen, I"ve updated the answer with few more ideas. Sorry for the long answer and the lack of explanations inside... if you need clarifications about some parts, please ping me :)
– pa4080
Jan 17 at 18:19
No problem at all - I really am looking to use this more as a reason to learn some shell scripting. I did in fact find a single line command which does exactly what I need!
– Charles Green
Jan 17 at 18:22
@CharlesGreen: Nice! It will be worth to write an answer.
– pa4080
Jan 17 at 18:34
I can certainly share the command, and will add it later. But your command answered a deeper question in prompting me to learn more about scripting
– Charles Green
Jan 17 at 18:59
|
show 1 more comment
Here is such script:
#!/bin/bash
# The destination where the new directory structure will be created
DEST="/tmp/new-order-pictures/"
MONTHS=('Jan' 'Feb' 'Mar' 'Apr' 'May' 'Jun' 'Jul' 'Aug' 'Sep' 'Oct' 'Nov' 'Dec')
# Walk through the first level directories, located in the current directory and go inside
for year in */
do
cd "$year"
# Walk through the months of the year
for month in "${MONTHS[@]}"
do
# Walk through the second level directories
for dir in */
do
# If we have coincidence between the name of the directory and the month
# go inside, make a new destination directory; ignore character cases^^
if [[ ${dir^^} =~ ${month^^} ]]
then
cd "$dir"
dest="${DEST}${year}${month}"
mkdir -p "$dest"
find . -type f | while IFS= read -r item
do
# Copy the files to the new destination and
# add the file's md5sum to its name to prevent files lose
filename=$(basename -- "$item")
extn="${filename##*.}"
name="${filename%.*}"
cp "$item" "${dest}/${name}-$(md5sum "$item" | cut -f1 -d' ').${extn}"
done
cd ..
fi
done
done
cd ..
done
The script should be executed in the first level directory where your images are located. You should tweak the destination directory - DEST="/tmp/new-order-pictures/"
. This version of the script relies that all files are in directories that contain the name of a month in one way or another. Example of usage:
user@host:~/Pictures$ tree .
.
├── 2013
│ ├── January 17, 2013
│ │ ├── Image1.jpg
│ │ └── Image 3.jpg
│ ├── January 24, 2013
│ │ └── Image2.jpg
│ ├── January 25, 2013
│ │ └── Image 3.jpg
│ ├── June 22, 2013
│ │ └── image1.jpg
│ ├── May 4, 2013
│ │ └── Image1.jpg
│ └── May 5, 2013
│ ├── Image1.jpg
│ └── Image 2.jpg
└── 2014
├── January 17, 2014
│ ├── Image1.jpg
│ └── Image 3.jpg
├── January 24, 2014
│ └── Image2.jpg
├── January 25, 2014
│ └── Image 3.jpg
└── May 5
├── Image1.jpg
└── Image 2.jpg
12 directories, 14 files
user@host:~/Pictures$ order.sh
user@host:~/Pictures$ tree /tmp/new-order-pictures/
/tmp/new-order-pictures/
├── 2013
│ ├── Jan
│ │ ├── Image1-7b71d9fdfe5b15a2d1a4968c195f93ae.jpg
│ │ ├── Image2-cbf4d36ff84e7ec24c05f8181236e6b8.jpg
│ │ ├── Image 3-0bca5188fd3f3eb470533fdaf0630633.jpg
│ │ └── Image 3-6a83880cae1aa57e19a7c45de7759e68.jpg
│ ├── Jun
│ │ └── image1-adb3bf995f1a25d008f758a7266d7be5.jpg
│ └── May
│ ├── Image1-511d541b35fcb38af8ada18d7961268c.jpg
│ ├── Image1-a66c5863e6986605cb2ca6d622ae72a0.jpg
│ └── Image 2-c34ffc32ce5d3901e1ad89b9fd15a877.jpg
└── 2014
├── Jan
│ ├── Image1-7b71d9fdfe5b15a2d1a4968c195f93ae.jpg
│ ├── Image2-cbf4d36ff84e7ec24c05f8181236e6b8.jpg
│ ├── Image 3-0bca5188fd3f3eb470533fdaf0630633.jpg
│ └── Image 3-6a83880cae1aa57e19a7c45de7759e68.jpg
└── May
├── Image1-511d541b35fcb38af8ada18d7961268c.jpg
└── Image 2-c34ffc32ce5d3901e1ad89b9fd15a877.jpg
7 directories, 14 files
In my case the script is named order.sh
and it is located in ~/bin
, thus I can use it as shell command. In the example you can see the directory structure is changed but the number of files is 14 in both structures.
Here is another version of the script that use mv
instead of cp
and will deal also with the files which are not in directories that contain the name of a month. Before running this script it is a good idea to create a backup copy of the original directory structure.
#!/bin/bash
# The destination where the new directory structure will be created
DEST="/tmp/new-order-pictures/"
MONTHS=('Jan' 'Feb' 'Mar' 'Apr' 'May' 'Jun' 'Jul' 'Aug' 'Sep' 'Oct' 'Nov' 'Dec')
# Walk through the first level directories, located in the current directory and go inside
for year in */
do
cd "$year"
# Walk through the months of the year
for month in "${MONTHS[@]}"
do
# Walk through the second level directories
for dir in */
do
# If we have coincidence between the name of the directory and the month
# go inside, make a new destination directory; ignore character cases^^
if [[ ${dir^^} =~ ${month^^} ]]
then
cd "$dir"
dest="${DEST}${year}${month}"
mkdir -p "$dest"
while IFS= read -r item
do
# Copy the files to the new destination and
# add the file's md5sum to its name to prevent files lose
filename=$(basename -- "$item")
extn="${filename##*.}"
name="${filename%.*}"
mv "$item" "${dest}/${name}-$(md5sum "$item" | cut -f1 -d' ').${extn}"
done < <(find . -type f)
cd ..
fi
done
done
# Dial with the rest of the files for that $year
dest="${DEST}${year}other"
while IFS= read -r item
do
mkdir -p "$dest"
filename=$(basename -- "$item")
extn="${filename##*.}"
name="${filename%.*}"
mv "$item" "${dest}/${name}-$(md5sum "$item" | cut -f1 -d' ').${extn}"
done < <(find . -type f)
cd ..
done
Example of usage:
user@host:~/Pictures$ tree .
.
├── 2013
│ ├── January 17, 2013
│ │ ├── Image1.jpg
│ │ ├── Image 3.jpg
│ │ └── video 7.mpg
│ ├── January 25, 2013
│ │ └── Image 3.jpg
│ ├── June 22, 2013
│ │ └── image1.jpg
│ └── May 5, 2013
│ ├── Image1.jpg
│ └── Image 2.jpg
└── 2014
├── Apr 7
│ ├── Image1.jpg
│ └── Image 2.jpg
├── Image 2.jpg
├── January 11, 2014
│ ├── Image1.jpg
│ └── Image 3.jpg
├── some other name
│ └── some other name file inside.jpg
├── some other name file inside.jpg
└── video 1.avi
9 directories, 15 files
user@host:~/Pictures$ order.sh
user@host:~/Pictures$ tree /tmp/new-order-pictures/
/tmp/new-order-pictures/
├── 2013
│ ├── Jan
│ │ ├── Image1-7b71d9fdfe5b15a2d1a4968c195f93ae.jpg
│ │ ├── Image 3-0bca5188fd3f3eb470533fdaf0630633.jpg
│ │ ├── Image 3-6a83880cae1aa57e19a7c45de7759e68.jpg
│ │ └── video 7-86764d9565469adfb22c8ef4f0b9c04f.mpg
│ ├── Jun
│ │ └── image1-adb3bf995f1a25d008f758a7266d7be5.jpg
│ └── May
│ ├── Image1-511d541b35fcb38af8ada18d7961268c.jpg
│ └── Image 2-c34ffc32ce5d3901e1ad89b9fd15a877.jpg
└── 2014
├── Apr
│ ├── Image1-3c19da25e0e56ef0fc752a9e4f75b190.jpg
│ └── Image 2-dcc35e86de393a014ac62e8c4390c7e6.jpg
├── Jan
│ ├── Image1-ae34289b0bc5258f286165745ff3c258.jpg
│ └── Image 3-1724adf2dfcc1d4a0dc50cb38ad2c510.jpg
└── other
├── Image 2-eff5208f7eee6a536e48f9982b918dfb.jpg
├── some other name file inside-7d0a68e0b4e9cc3928744cb83f4d1136.jpg
├── some other name file inside-c2dd637e94a9025c3e1004d66f59539c.jpg
└── video 1-c277d93a2427bedf3f0b8ae07427edb9.avi
8 directories, 15 files
After that you can go inside the destination directory and use the rename
command within for
loop to deal with the long names:
# For each directory on the second level
for dir in */*
do
cd "$dir"
rename 's/^.*(.[0-9a-zA-Z]+)$/our $i; sprintf("Image-%03d$1", 1+$i++)/e' *
cd ..
cd ..
done
Example:
user@host:~/Pictures$ cd /tmp/new-order-pictures/
user@host:/tmp/new-order-pictures$ for dir in */*; do cd "$dir"; rename 's/^.*(.[0-9a-zA-Z]+)$/our $i; sprintf("Image-%03d$1", 1+$i++)/e' *; cd ..; cd ..; done
user@host:/tmp/new-order-pictures$ tree .
.
├── 2013
│ ├── Jan
│ │ ├── Image-001.jpg
│ │ ├── Image-002.jpg
│ │ ├── Image-003.jpg
│ │ └── Image-004.mpg
│ ├── Jun
│ │ └── Image-001.jpg
│ └── May
│ ├── Image-001.jpg
│ └── Image-002.jpg
└── 2014
├── Apr
│ ├── Image-001.jpg
│ └── Image-002.jpg
├── Jan
│ ├── Image-001.jpg
│ └── Image-002.jpg
└── other
├── Image-001.jpg
├── Image-002.jpg
├── Image-003.jpg
└── Image-004.avi
8 directories, 15 files
Or you can change (.[0-9a-zA-Z]+)
with (.jpg)
, then on next iteration with (.mpg)
(respectively Image-
with Video-
), etc. References about this usage of rename
:
How to rename multiple files sequentially from command line?
Renaming hundreds of files at once for proper sorting
Thanks! I think this is really close to what I asked for, and I'll have to scour the web looking for shell expansions et al...
– Charles Green
Jan 17 at 15:05
Hi, @CharlesGreen, I"ve updated the answer with few more ideas. Sorry for the long answer and the lack of explanations inside... if you need clarifications about some parts, please ping me :)
– pa4080
Jan 17 at 18:19
No problem at all - I really am looking to use this more as a reason to learn some shell scripting. I did in fact find a single line command which does exactly what I need!
– Charles Green
Jan 17 at 18:22
@CharlesGreen: Nice! It will be worth to write an answer.
– pa4080
Jan 17 at 18:34
I can certainly share the command, and will add it later. But your command answered a deeper question in prompting me to learn more about scripting
– Charles Green
Jan 17 at 18:59
|
show 1 more comment
Here is such script:
#!/bin/bash
# The destination where the new directory structure will be created
DEST="/tmp/new-order-pictures/"
MONTHS=('Jan' 'Feb' 'Mar' 'Apr' 'May' 'Jun' 'Jul' 'Aug' 'Sep' 'Oct' 'Nov' 'Dec')
# Walk through the first level directories, located in the current directory and go inside
for year in */
do
cd "$year"
# Walk through the months of the year
for month in "${MONTHS[@]}"
do
# Walk through the second level directories
for dir in */
do
# If we have coincidence between the name of the directory and the month
# go inside, make a new destination directory; ignore character cases^^
if [[ ${dir^^} =~ ${month^^} ]]
then
cd "$dir"
dest="${DEST}${year}${month}"
mkdir -p "$dest"
find . -type f | while IFS= read -r item
do
# Copy the files to the new destination and
# add the file's md5sum to its name to prevent files lose
filename=$(basename -- "$item")
extn="${filename##*.}"
name="${filename%.*}"
cp "$item" "${dest}/${name}-$(md5sum "$item" | cut -f1 -d' ').${extn}"
done
cd ..
fi
done
done
cd ..
done
The script should be executed in the first level directory where your images are located. You should tweak the destination directory - DEST="/tmp/new-order-pictures/"
. This version of the script relies that all files are in directories that contain the name of a month in one way or another. Example of usage:
user@host:~/Pictures$ tree .
.
├── 2013
│ ├── January 17, 2013
│ │ ├── Image1.jpg
│ │ └── Image 3.jpg
│ ├── January 24, 2013
│ │ └── Image2.jpg
│ ├── January 25, 2013
│ │ └── Image 3.jpg
│ ├── June 22, 2013
│ │ └── image1.jpg
│ ├── May 4, 2013
│ │ └── Image1.jpg
│ └── May 5, 2013
│ ├── Image1.jpg
│ └── Image 2.jpg
└── 2014
├── January 17, 2014
│ ├── Image1.jpg
│ └── Image 3.jpg
├── January 24, 2014
│ └── Image2.jpg
├── January 25, 2014
│ └── Image 3.jpg
└── May 5
├── Image1.jpg
└── Image 2.jpg
12 directories, 14 files
user@host:~/Pictures$ order.sh
user@host:~/Pictures$ tree /tmp/new-order-pictures/
/tmp/new-order-pictures/
├── 2013
│ ├── Jan
│ │ ├── Image1-7b71d9fdfe5b15a2d1a4968c195f93ae.jpg
│ │ ├── Image2-cbf4d36ff84e7ec24c05f8181236e6b8.jpg
│ │ ├── Image 3-0bca5188fd3f3eb470533fdaf0630633.jpg
│ │ └── Image 3-6a83880cae1aa57e19a7c45de7759e68.jpg
│ ├── Jun
│ │ └── image1-adb3bf995f1a25d008f758a7266d7be5.jpg
│ └── May
│ ├── Image1-511d541b35fcb38af8ada18d7961268c.jpg
│ ├── Image1-a66c5863e6986605cb2ca6d622ae72a0.jpg
│ └── Image 2-c34ffc32ce5d3901e1ad89b9fd15a877.jpg
└── 2014
├── Jan
│ ├── Image1-7b71d9fdfe5b15a2d1a4968c195f93ae.jpg
│ ├── Image2-cbf4d36ff84e7ec24c05f8181236e6b8.jpg
│ ├── Image 3-0bca5188fd3f3eb470533fdaf0630633.jpg
│ └── Image 3-6a83880cae1aa57e19a7c45de7759e68.jpg
└── May
├── Image1-511d541b35fcb38af8ada18d7961268c.jpg
└── Image 2-c34ffc32ce5d3901e1ad89b9fd15a877.jpg
7 directories, 14 files
In my case the script is named order.sh
and it is located in ~/bin
, thus I can use it as shell command. In the example you can see the directory structure is changed but the number of files is 14 in both structures.
Here is another version of the script that use mv
instead of cp
and will deal also with the files which are not in directories that contain the name of a month. Before running this script it is a good idea to create a backup copy of the original directory structure.
#!/bin/bash
# The destination where the new directory structure will be created
DEST="/tmp/new-order-pictures/"
MONTHS=('Jan' 'Feb' 'Mar' 'Apr' 'May' 'Jun' 'Jul' 'Aug' 'Sep' 'Oct' 'Nov' 'Dec')
# Walk through the first level directories, located in the current directory and go inside
for year in */
do
cd "$year"
# Walk through the months of the year
for month in "${MONTHS[@]}"
do
# Walk through the second level directories
for dir in */
do
# If we have coincidence between the name of the directory and the month
# go inside, make a new destination directory; ignore character cases^^
if [[ ${dir^^} =~ ${month^^} ]]
then
cd "$dir"
dest="${DEST}${year}${month}"
mkdir -p "$dest"
while IFS= read -r item
do
# Copy the files to the new destination and
# add the file's md5sum to its name to prevent files lose
filename=$(basename -- "$item")
extn="${filename##*.}"
name="${filename%.*}"
mv "$item" "${dest}/${name}-$(md5sum "$item" | cut -f1 -d' ').${extn}"
done < <(find . -type f)
cd ..
fi
done
done
# Dial with the rest of the files for that $year
dest="${DEST}${year}other"
while IFS= read -r item
do
mkdir -p "$dest"
filename=$(basename -- "$item")
extn="${filename##*.}"
name="${filename%.*}"
mv "$item" "${dest}/${name}-$(md5sum "$item" | cut -f1 -d' ').${extn}"
done < <(find . -type f)
cd ..
done
Example of usage:
user@host:~/Pictures$ tree .
.
├── 2013
│ ├── January 17, 2013
│ │ ├── Image1.jpg
│ │ ├── Image 3.jpg
│ │ └── video 7.mpg
│ ├── January 25, 2013
│ │ └── Image 3.jpg
│ ├── June 22, 2013
│ │ └── image1.jpg
│ └── May 5, 2013
│ ├── Image1.jpg
│ └── Image 2.jpg
└── 2014
├── Apr 7
│ ├── Image1.jpg
│ └── Image 2.jpg
├── Image 2.jpg
├── January 11, 2014
│ ├── Image1.jpg
│ └── Image 3.jpg
├── some other name
│ └── some other name file inside.jpg
├── some other name file inside.jpg
└── video 1.avi
9 directories, 15 files
user@host:~/Pictures$ order.sh
user@host:~/Pictures$ tree /tmp/new-order-pictures/
/tmp/new-order-pictures/
├── 2013
│ ├── Jan
│ │ ├── Image1-7b71d9fdfe5b15a2d1a4968c195f93ae.jpg
│ │ ├── Image 3-0bca5188fd3f3eb470533fdaf0630633.jpg
│ │ ├── Image 3-6a83880cae1aa57e19a7c45de7759e68.jpg
│ │ └── video 7-86764d9565469adfb22c8ef4f0b9c04f.mpg
│ ├── Jun
│ │ └── image1-adb3bf995f1a25d008f758a7266d7be5.jpg
│ └── May
│ ├── Image1-511d541b35fcb38af8ada18d7961268c.jpg
│ └── Image 2-c34ffc32ce5d3901e1ad89b9fd15a877.jpg
└── 2014
├── Apr
│ ├── Image1-3c19da25e0e56ef0fc752a9e4f75b190.jpg
│ └── Image 2-dcc35e86de393a014ac62e8c4390c7e6.jpg
├── Jan
│ ├── Image1-ae34289b0bc5258f286165745ff3c258.jpg
│ └── Image 3-1724adf2dfcc1d4a0dc50cb38ad2c510.jpg
└── other
├── Image 2-eff5208f7eee6a536e48f9982b918dfb.jpg
├── some other name file inside-7d0a68e0b4e9cc3928744cb83f4d1136.jpg
├── some other name file inside-c2dd637e94a9025c3e1004d66f59539c.jpg
└── video 1-c277d93a2427bedf3f0b8ae07427edb9.avi
8 directories, 15 files
After that you can go inside the destination directory and use the rename
command within for
loop to deal with the long names:
# For each directory on the second level
for dir in */*
do
cd "$dir"
rename 's/^.*(.[0-9a-zA-Z]+)$/our $i; sprintf("Image-%03d$1", 1+$i++)/e' *
cd ..
cd ..
done
Example:
user@host:~/Pictures$ cd /tmp/new-order-pictures/
user@host:/tmp/new-order-pictures$ for dir in */*; do cd "$dir"; rename 's/^.*(.[0-9a-zA-Z]+)$/our $i; sprintf("Image-%03d$1", 1+$i++)/e' *; cd ..; cd ..; done
user@host:/tmp/new-order-pictures$ tree .
.
├── 2013
│ ├── Jan
│ │ ├── Image-001.jpg
│ │ ├── Image-002.jpg
│ │ ├── Image-003.jpg
│ │ └── Image-004.mpg
│ ├── Jun
│ │ └── Image-001.jpg
│ └── May
│ ├── Image-001.jpg
│ └── Image-002.jpg
└── 2014
├── Apr
│ ├── Image-001.jpg
│ └── Image-002.jpg
├── Jan
│ ├── Image-001.jpg
│ └── Image-002.jpg
└── other
├── Image-001.jpg
├── Image-002.jpg
├── Image-003.jpg
└── Image-004.avi
8 directories, 15 files
Or you can change (.[0-9a-zA-Z]+)
with (.jpg)
, then on next iteration with (.mpg)
(respectively Image-
with Video-
), etc. References about this usage of rename
:
How to rename multiple files sequentially from command line?
Renaming hundreds of files at once for proper sorting
Here is such script:
#!/bin/bash
# The destination where the new directory structure will be created
DEST="/tmp/new-order-pictures/"
MONTHS=('Jan' 'Feb' 'Mar' 'Apr' 'May' 'Jun' 'Jul' 'Aug' 'Sep' 'Oct' 'Nov' 'Dec')
# Walk through the first level directories, located in the current directory and go inside
for year in */
do
cd "$year"
# Walk through the months of the year
for month in "${MONTHS[@]}"
do
# Walk through the second level directories
for dir in */
do
# If we have coincidence between the name of the directory and the month
# go inside, make a new destination directory; ignore character cases^^
if [[ ${dir^^} =~ ${month^^} ]]
then
cd "$dir"
dest="${DEST}${year}${month}"
mkdir -p "$dest"
find . -type f | while IFS= read -r item
do
# Copy the files to the new destination and
# add the file's md5sum to its name to prevent files lose
filename=$(basename -- "$item")
extn="${filename##*.}"
name="${filename%.*}"
cp "$item" "${dest}/${name}-$(md5sum "$item" | cut -f1 -d' ').${extn}"
done
cd ..
fi
done
done
cd ..
done
The script should be executed in the first level directory where your images are located. You should tweak the destination directory - DEST="/tmp/new-order-pictures/"
. This version of the script relies that all files are in directories that contain the name of a month in one way or another. Example of usage:
user@host:~/Pictures$ tree .
.
├── 2013
│ ├── January 17, 2013
│ │ ├── Image1.jpg
│ │ └── Image 3.jpg
│ ├── January 24, 2013
│ │ └── Image2.jpg
│ ├── January 25, 2013
│ │ └── Image 3.jpg
│ ├── June 22, 2013
│ │ └── image1.jpg
│ ├── May 4, 2013
│ │ └── Image1.jpg
│ └── May 5, 2013
│ ├── Image1.jpg
│ └── Image 2.jpg
└── 2014
├── January 17, 2014
│ ├── Image1.jpg
│ └── Image 3.jpg
├── January 24, 2014
│ └── Image2.jpg
├── January 25, 2014
│ └── Image 3.jpg
└── May 5
├── Image1.jpg
└── Image 2.jpg
12 directories, 14 files
user@host:~/Pictures$ order.sh
user@host:~/Pictures$ tree /tmp/new-order-pictures/
/tmp/new-order-pictures/
├── 2013
│ ├── Jan
│ │ ├── Image1-7b71d9fdfe5b15a2d1a4968c195f93ae.jpg
│ │ ├── Image2-cbf4d36ff84e7ec24c05f8181236e6b8.jpg
│ │ ├── Image 3-0bca5188fd3f3eb470533fdaf0630633.jpg
│ │ └── Image 3-6a83880cae1aa57e19a7c45de7759e68.jpg
│ ├── Jun
│ │ └── image1-adb3bf995f1a25d008f758a7266d7be5.jpg
│ └── May
│ ├── Image1-511d541b35fcb38af8ada18d7961268c.jpg
│ ├── Image1-a66c5863e6986605cb2ca6d622ae72a0.jpg
│ └── Image 2-c34ffc32ce5d3901e1ad89b9fd15a877.jpg
└── 2014
├── Jan
│ ├── Image1-7b71d9fdfe5b15a2d1a4968c195f93ae.jpg
│ ├── Image2-cbf4d36ff84e7ec24c05f8181236e6b8.jpg
│ ├── Image 3-0bca5188fd3f3eb470533fdaf0630633.jpg
│ └── Image 3-6a83880cae1aa57e19a7c45de7759e68.jpg
└── May
├── Image1-511d541b35fcb38af8ada18d7961268c.jpg
└── Image 2-c34ffc32ce5d3901e1ad89b9fd15a877.jpg
7 directories, 14 files
In my case the script is named order.sh
and it is located in ~/bin
, thus I can use it as shell command. In the example you can see the directory structure is changed but the number of files is 14 in both structures.
Here is another version of the script that use mv
instead of cp
and will deal also with the files which are not in directories that contain the name of a month. Before running this script it is a good idea to create a backup copy of the original directory structure.
#!/bin/bash
# The destination where the new directory structure will be created
DEST="/tmp/new-order-pictures/"
MONTHS=('Jan' 'Feb' 'Mar' 'Apr' 'May' 'Jun' 'Jul' 'Aug' 'Sep' 'Oct' 'Nov' 'Dec')
# Walk through the first level directories, located in the current directory and go inside
for year in */
do
cd "$year"
# Walk through the months of the year
for month in "${MONTHS[@]}"
do
# Walk through the second level directories
for dir in */
do
# If we have coincidence between the name of the directory and the month
# go inside, make a new destination directory; ignore character cases^^
if [[ ${dir^^} =~ ${month^^} ]]
then
cd "$dir"
dest="${DEST}${year}${month}"
mkdir -p "$dest"
while IFS= read -r item
do
# Copy the files to the new destination and
# add the file's md5sum to its name to prevent files lose
filename=$(basename -- "$item")
extn="${filename##*.}"
name="${filename%.*}"
mv "$item" "${dest}/${name}-$(md5sum "$item" | cut -f1 -d' ').${extn}"
done < <(find . -type f)
cd ..
fi
done
done
# Dial with the rest of the files for that $year
dest="${DEST}${year}other"
while IFS= read -r item
do
mkdir -p "$dest"
filename=$(basename -- "$item")
extn="${filename##*.}"
name="${filename%.*}"
mv "$item" "${dest}/${name}-$(md5sum "$item" | cut -f1 -d' ').${extn}"
done < <(find . -type f)
cd ..
done
Example of usage:
user@host:~/Pictures$ tree .
.
├── 2013
│ ├── January 17, 2013
│ │ ├── Image1.jpg
│ │ ├── Image 3.jpg
│ │ └── video 7.mpg
│ ├── January 25, 2013
│ │ └── Image 3.jpg
│ ├── June 22, 2013
│ │ └── image1.jpg
│ └── May 5, 2013
│ ├── Image1.jpg
│ └── Image 2.jpg
└── 2014
├── Apr 7
│ ├── Image1.jpg
│ └── Image 2.jpg
├── Image 2.jpg
├── January 11, 2014
│ ├── Image1.jpg
│ └── Image 3.jpg
├── some other name
│ └── some other name file inside.jpg
├── some other name file inside.jpg
└── video 1.avi
9 directories, 15 files
user@host:~/Pictures$ order.sh
user@host:~/Pictures$ tree /tmp/new-order-pictures/
/tmp/new-order-pictures/
├── 2013
│ ├── Jan
│ │ ├── Image1-7b71d9fdfe5b15a2d1a4968c195f93ae.jpg
│ │ ├── Image 3-0bca5188fd3f3eb470533fdaf0630633.jpg
│ │ ├── Image 3-6a83880cae1aa57e19a7c45de7759e68.jpg
│ │ └── video 7-86764d9565469adfb22c8ef4f0b9c04f.mpg
│ ├── Jun
│ │ └── image1-adb3bf995f1a25d008f758a7266d7be5.jpg
│ └── May
│ ├── Image1-511d541b35fcb38af8ada18d7961268c.jpg
│ └── Image 2-c34ffc32ce5d3901e1ad89b9fd15a877.jpg
└── 2014
├── Apr
│ ├── Image1-3c19da25e0e56ef0fc752a9e4f75b190.jpg
│ └── Image 2-dcc35e86de393a014ac62e8c4390c7e6.jpg
├── Jan
│ ├── Image1-ae34289b0bc5258f286165745ff3c258.jpg
│ └── Image 3-1724adf2dfcc1d4a0dc50cb38ad2c510.jpg
└── other
├── Image 2-eff5208f7eee6a536e48f9982b918dfb.jpg
├── some other name file inside-7d0a68e0b4e9cc3928744cb83f4d1136.jpg
├── some other name file inside-c2dd637e94a9025c3e1004d66f59539c.jpg
└── video 1-c277d93a2427bedf3f0b8ae07427edb9.avi
8 directories, 15 files
After that you can go inside the destination directory and use the rename
command within for
loop to deal with the long names:
# For each directory on the second level
for dir in */*
do
cd "$dir"
rename 's/^.*(.[0-9a-zA-Z]+)$/our $i; sprintf("Image-%03d$1", 1+$i++)/e' *
cd ..
cd ..
done
Example:
user@host:~/Pictures$ cd /tmp/new-order-pictures/
user@host:/tmp/new-order-pictures$ for dir in */*; do cd "$dir"; rename 's/^.*(.[0-9a-zA-Z]+)$/our $i; sprintf("Image-%03d$1", 1+$i++)/e' *; cd ..; cd ..; done
user@host:/tmp/new-order-pictures$ tree .
.
├── 2013
│ ├── Jan
│ │ ├── Image-001.jpg
│ │ ├── Image-002.jpg
│ │ ├── Image-003.jpg
│ │ └── Image-004.mpg
│ ├── Jun
│ │ └── Image-001.jpg
│ └── May
│ ├── Image-001.jpg
│ └── Image-002.jpg
└── 2014
├── Apr
│ ├── Image-001.jpg
│ └── Image-002.jpg
├── Jan
│ ├── Image-001.jpg
│ └── Image-002.jpg
└── other
├── Image-001.jpg
├── Image-002.jpg
├── Image-003.jpg
└── Image-004.avi
8 directories, 15 files
Or you can change (.[0-9a-zA-Z]+)
with (.jpg)
, then on next iteration with (.mpg)
(respectively Image-
with Video-
), etc. References about this usage of rename
:
How to rename multiple files sequentially from command line?
Renaming hundreds of files at once for proper sorting
edited Jan 17 at 18:21
answered Jan 17 at 10:54
pa4080pa4080
14.3k52669
14.3k52669
Thanks! I think this is really close to what I asked for, and I'll have to scour the web looking for shell expansions et al...
– Charles Green
Jan 17 at 15:05
Hi, @CharlesGreen, I"ve updated the answer with few more ideas. Sorry for the long answer and the lack of explanations inside... if you need clarifications about some parts, please ping me :)
– pa4080
Jan 17 at 18:19
No problem at all - I really am looking to use this more as a reason to learn some shell scripting. I did in fact find a single line command which does exactly what I need!
– Charles Green
Jan 17 at 18:22
@CharlesGreen: Nice! It will be worth to write an answer.
– pa4080
Jan 17 at 18:34
I can certainly share the command, and will add it later. But your command answered a deeper question in prompting me to learn more about scripting
– Charles Green
Jan 17 at 18:59
|
show 1 more comment
Thanks! I think this is really close to what I asked for, and I'll have to scour the web looking for shell expansions et al...
– Charles Green
Jan 17 at 15:05
Hi, @CharlesGreen, I"ve updated the answer with few more ideas. Sorry for the long answer and the lack of explanations inside... if you need clarifications about some parts, please ping me :)
– pa4080
Jan 17 at 18:19
No problem at all - I really am looking to use this more as a reason to learn some shell scripting. I did in fact find a single line command which does exactly what I need!
– Charles Green
Jan 17 at 18:22
@CharlesGreen: Nice! It will be worth to write an answer.
– pa4080
Jan 17 at 18:34
I can certainly share the command, and will add it later. But your command answered a deeper question in prompting me to learn more about scripting
– Charles Green
Jan 17 at 18:59
Thanks! I think this is really close to what I asked for, and I'll have to scour the web looking for shell expansions et al...
– Charles Green
Jan 17 at 15:05
Thanks! I think this is really close to what I asked for, and I'll have to scour the web looking for shell expansions et al...
– Charles Green
Jan 17 at 15:05
Hi, @CharlesGreen, I"ve updated the answer with few more ideas. Sorry for the long answer and the lack of explanations inside... if you need clarifications about some parts, please ping me :)
– pa4080
Jan 17 at 18:19
Hi, @CharlesGreen, I"ve updated the answer with few more ideas. Sorry for the long answer and the lack of explanations inside... if you need clarifications about some parts, please ping me :)
– pa4080
Jan 17 at 18:19
No problem at all - I really am looking to use this more as a reason to learn some shell scripting. I did in fact find a single line command which does exactly what I need!
– Charles Green
Jan 17 at 18:22
No problem at all - I really am looking to use this more as a reason to learn some shell scripting. I did in fact find a single line command which does exactly what I need!
– Charles Green
Jan 17 at 18:22
@CharlesGreen: Nice! It will be worth to write an answer.
– pa4080
Jan 17 at 18:34
@CharlesGreen: Nice! It will be worth to write an answer.
– pa4080
Jan 17 at 18:34
I can certainly share the command, and will add it later. But your command answered a deeper question in prompting me to learn more about scripting
– Charles Green
Jan 17 at 18:59
I can certainly share the command, and will add it later. But your command answered a deeper question in prompting me to learn more about scripting
– Charles Green
Jan 17 at 18:59
|
show 1 more comment
There is an application which can move and rename the files in a single command line - exiftool
sudo apt install libimage-exiftool-perl
In my case, the specific command line used was
exiftool '-FileName<DateTimeOriginal' -d <path-to-output-dir>/%Y/%m-%B/%Y%m%d_%H%M%S%%-c.%%e . -r
or
exiftool '-FileName<CreateDate' -d <path-to-output-dir>/%Y/%m-%B/%Y%m%d_%H%M%S%%-c.%%e . -r
depending upon which tag is present in the images. If the requested tag is not present, the application throws a warning and does not move that file, but continues processing. This application also handles multiple images with the same date/time by appending a numeric to the end of the filename.
I did have several images without exif data, and I was able to add exif data to the images with the command
exiftool -createdate='2011:12:04 12:00:00' * -overwrite_original
As an example, I placed some images in a directory ~/aa/test1 and ran the tool, placing the output in ~/aa/test2. The results are below:
chick@dad:~/aa$ tree .
.
├── test1
│ ├── DSC00018.JPG
│ ├── DSC00022.JPG
│ ├── DSC00024.JPG
│ ├── DSC00025.JPG
│ ├── DSC00026.JPG
│ ├── DSC00028.JPG
│ ├── DSC00031.JPG
│ ├── DSC00033.JPG
│ └── Thumbs.db
└── test2
└── 2000
└── 12-December
├── 20001222_185523.JPG
├── 20001222_200726.JPG
├── 20001222_200819.JPG
├── 20001222_201205.JPG
├── 20001222_201223.JPG
├── 20001222_210536.JPG
├── 20001222_211858.JPG
└── 20001222_215950.JPG
Superb! You may accept this answer, because of its simplicity :) Yesterday when I made the last edit on my answer, I realizedrename
can be used in similar way as it is made here, but I do not have time to elaborate.
– pa4080
Jan 18 at 17:33
1
@pa4080 But I still like your answer, because it will cause me to work seeper into scripting...!
– Charles Green
Jan 18 at 17:36
add a comment |
There is an application which can move and rename the files in a single command line - exiftool
sudo apt install libimage-exiftool-perl
In my case, the specific command line used was
exiftool '-FileName<DateTimeOriginal' -d <path-to-output-dir>/%Y/%m-%B/%Y%m%d_%H%M%S%%-c.%%e . -r
or
exiftool '-FileName<CreateDate' -d <path-to-output-dir>/%Y/%m-%B/%Y%m%d_%H%M%S%%-c.%%e . -r
depending upon which tag is present in the images. If the requested tag is not present, the application throws a warning and does not move that file, but continues processing. This application also handles multiple images with the same date/time by appending a numeric to the end of the filename.
I did have several images without exif data, and I was able to add exif data to the images with the command
exiftool -createdate='2011:12:04 12:00:00' * -overwrite_original
As an example, I placed some images in a directory ~/aa/test1 and ran the tool, placing the output in ~/aa/test2. The results are below:
chick@dad:~/aa$ tree .
.
├── test1
│ ├── DSC00018.JPG
│ ├── DSC00022.JPG
│ ├── DSC00024.JPG
│ ├── DSC00025.JPG
│ ├── DSC00026.JPG
│ ├── DSC00028.JPG
│ ├── DSC00031.JPG
│ ├── DSC00033.JPG
│ └── Thumbs.db
└── test2
└── 2000
└── 12-December
├── 20001222_185523.JPG
├── 20001222_200726.JPG
├── 20001222_200819.JPG
├── 20001222_201205.JPG
├── 20001222_201223.JPG
├── 20001222_210536.JPG
├── 20001222_211858.JPG
└── 20001222_215950.JPG
Superb! You may accept this answer, because of its simplicity :) Yesterday when I made the last edit on my answer, I realizedrename
can be used in similar way as it is made here, but I do not have time to elaborate.
– pa4080
Jan 18 at 17:33
1
@pa4080 But I still like your answer, because it will cause me to work seeper into scripting...!
– Charles Green
Jan 18 at 17:36
add a comment |
There is an application which can move and rename the files in a single command line - exiftool
sudo apt install libimage-exiftool-perl
In my case, the specific command line used was
exiftool '-FileName<DateTimeOriginal' -d <path-to-output-dir>/%Y/%m-%B/%Y%m%d_%H%M%S%%-c.%%e . -r
or
exiftool '-FileName<CreateDate' -d <path-to-output-dir>/%Y/%m-%B/%Y%m%d_%H%M%S%%-c.%%e . -r
depending upon which tag is present in the images. If the requested tag is not present, the application throws a warning and does not move that file, but continues processing. This application also handles multiple images with the same date/time by appending a numeric to the end of the filename.
I did have several images without exif data, and I was able to add exif data to the images with the command
exiftool -createdate='2011:12:04 12:00:00' * -overwrite_original
As an example, I placed some images in a directory ~/aa/test1 and ran the tool, placing the output in ~/aa/test2. The results are below:
chick@dad:~/aa$ tree .
.
├── test1
│ ├── DSC00018.JPG
│ ├── DSC00022.JPG
│ ├── DSC00024.JPG
│ ├── DSC00025.JPG
│ ├── DSC00026.JPG
│ ├── DSC00028.JPG
│ ├── DSC00031.JPG
│ ├── DSC00033.JPG
│ └── Thumbs.db
└── test2
└── 2000
└── 12-December
├── 20001222_185523.JPG
├── 20001222_200726.JPG
├── 20001222_200819.JPG
├── 20001222_201205.JPG
├── 20001222_201223.JPG
├── 20001222_210536.JPG
├── 20001222_211858.JPG
└── 20001222_215950.JPG
There is an application which can move and rename the files in a single command line - exiftool
sudo apt install libimage-exiftool-perl
In my case, the specific command line used was
exiftool '-FileName<DateTimeOriginal' -d <path-to-output-dir>/%Y/%m-%B/%Y%m%d_%H%M%S%%-c.%%e . -r
or
exiftool '-FileName<CreateDate' -d <path-to-output-dir>/%Y/%m-%B/%Y%m%d_%H%M%S%%-c.%%e . -r
depending upon which tag is present in the images. If the requested tag is not present, the application throws a warning and does not move that file, but continues processing. This application also handles multiple images with the same date/time by appending a numeric to the end of the filename.
I did have several images without exif data, and I was able to add exif data to the images with the command
exiftool -createdate='2011:12:04 12:00:00' * -overwrite_original
As an example, I placed some images in a directory ~/aa/test1 and ran the tool, placing the output in ~/aa/test2. The results are below:
chick@dad:~/aa$ tree .
.
├── test1
│ ├── DSC00018.JPG
│ ├── DSC00022.JPG
│ ├── DSC00024.JPG
│ ├── DSC00025.JPG
│ ├── DSC00026.JPG
│ ├── DSC00028.JPG
│ ├── DSC00031.JPG
│ ├── DSC00033.JPG
│ └── Thumbs.db
└── test2
└── 2000
└── 12-December
├── 20001222_185523.JPG
├── 20001222_200726.JPG
├── 20001222_200819.JPG
├── 20001222_201205.JPG
├── 20001222_201223.JPG
├── 20001222_210536.JPG
├── 20001222_211858.JPG
└── 20001222_215950.JPG
answered Jan 18 at 16:49
Charles GreenCharles Green
13.7k73858
13.7k73858
Superb! You may accept this answer, because of its simplicity :) Yesterday when I made the last edit on my answer, I realizedrename
can be used in similar way as it is made here, but I do not have time to elaborate.
– pa4080
Jan 18 at 17:33
1
@pa4080 But I still like your answer, because it will cause me to work seeper into scripting...!
– Charles Green
Jan 18 at 17:36
add a comment |
Superb! You may accept this answer, because of its simplicity :) Yesterday when I made the last edit on my answer, I realizedrename
can be used in similar way as it is made here, but I do not have time to elaborate.
– pa4080
Jan 18 at 17:33
1
@pa4080 But I still like your answer, because it will cause me to work seeper into scripting...!
– Charles Green
Jan 18 at 17:36
Superb! You may accept this answer, because of its simplicity :) Yesterday when I made the last edit on my answer, I realized
rename
can be used in similar way as it is made here, but I do not have time to elaborate.– pa4080
Jan 18 at 17:33
Superb! You may accept this answer, because of its simplicity :) Yesterday when I made the last edit on my answer, I realized
rename
can be used in similar way as it is made here, but I do not have time to elaborate.– pa4080
Jan 18 at 17:33
1
1
@pa4080 But I still like your answer, because it will cause me to work seeper into scripting...!
– Charles Green
Jan 18 at 17:36
@pa4080 But I still like your answer, because it will cause me to work seeper into scripting...!
– Charles Green
Jan 18 at 17:36
add a comment |
So, I assume you want a step-by-step and simple solution.
First, I would address the problem of Whitespace and comma in the folders.
I would first cd into the year folder and use rename
to first remove Whitespace
rename "s/ //g" *
Similarly, remove comma
rename "s/,//g" *
Now that I have all the folders as desired I would create a month based list using
ls | grep "January" > January.txt
Now make folder "January"
mkdir January
Then loop thru the list using xargs
to copy their contents
cat January.txt | xargs -I {} cp -R {}/. ./January/
add a comment |
So, I assume you want a step-by-step and simple solution.
First, I would address the problem of Whitespace and comma in the folders.
I would first cd into the year folder and use rename
to first remove Whitespace
rename "s/ //g" *
Similarly, remove comma
rename "s/,//g" *
Now that I have all the folders as desired I would create a month based list using
ls | grep "January" > January.txt
Now make folder "January"
mkdir January
Then loop thru the list using xargs
to copy their contents
cat January.txt | xargs -I {} cp -R {}/. ./January/
add a comment |
So, I assume you want a step-by-step and simple solution.
First, I would address the problem of Whitespace and comma in the folders.
I would first cd into the year folder and use rename
to first remove Whitespace
rename "s/ //g" *
Similarly, remove comma
rename "s/,//g" *
Now that I have all the folders as desired I would create a month based list using
ls | grep "January" > January.txt
Now make folder "January"
mkdir January
Then loop thru the list using xargs
to copy their contents
cat January.txt | xargs -I {} cp -R {}/. ./January/
So, I assume you want a step-by-step and simple solution.
First, I would address the problem of Whitespace and comma in the folders.
I would first cd into the year folder and use rename
to first remove Whitespace
rename "s/ //g" *
Similarly, remove comma
rename "s/,//g" *
Now that I have all the folders as desired I would create a month based list using
ls | grep "January" > January.txt
Now make folder "January"
mkdir January
Then loop thru the list using xargs
to copy their contents
cat January.txt | xargs -I {} cp -R {}/. ./January/
answered Jan 17 at 14:41
puneetpuneet
11
11
add a comment |
add a comment |
Thanks for contributing an answer to Ask Ubuntu!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2faskubuntu.com%2fquestions%2f1110359%2fmove-files-from-subfolders%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
I'd want to rename the images first, probably adding the full date, otherwise it looks like they'll overwrite each other if moved to a common directory. If the file's dates match their folder's dates that might be easier than using the file's path..
– Xen2050
Jan 16 at 23:14
@Xen2050 Thanks - the file naming has changed over the years as cameras were bought and destroyed... but I think I have a fairly elegant solution. It unfortunately does not advance my knowledge of scripting...
exiftool '-FileName<DateTimeOriginal' -d %Y/%m-%B/%f%%-c.%%e . -r
-> it's almost perfect, except for some .mov files which do not have exif data– Charles Green
Jan 17 at 0:28