Loop folders with certain string in name

Started by Windwalker, April 12, 2020, 08:24:57 AM

Previous topic - Next topic

Windwalker

Hello,

recently I started working with ExifTool in order to clean up my photo collection.

I try to use ExifTool in combination with some Windows CMD batch processing; but of course I am also open for any other, maybe ExifTool-only (without batch script) solution.
I would greatly appreciate if you would like to help me.

This is what my problem is all about:

I keep photos in parallel directories, named after the date these photos were taken, let's say "YYYY-MM-DD".
I am working with Lightroom, to identify the best of the images I took. For these best images, I use Lightroom's "export feature", to create the best images in a sub folder named "top". Therefore, over the years working with Lightroom, I got the following directory structure:

  • <Pictures Root Directory>

    • 2018-01-01

      • top
    • 2018-03-05

      • top
    • 2019-06-02

      • top
    • 2019-08-04

      • top

And so on...

Now I want to start ExifTool in <Pictures Root Directory> and enter each of the photo directories and, if present, enter the sub folders "top" and copy these images (along with some processing) onto my network storage.

For individual folders and manual invocation, I built the following ExifTool command, which works fine:
exiftool -d %Y-%m-%d-%H-%M-%S%%-c.%%e "-filename<${Make}_${Model}_${DateTimeOriginal}" -execute -o . "-Directory<DateTimeOriginal" -d "<Network Drive>\images\%Y\%Y-%m-%d" -common_args "."
This command renames all image filenames to pattern: <Camera>_<Model>_YYYY-MM-DD-HH-MM.jpg and then copies them to my network drive.

Apparently ExifTool does not support wildcard patterns in directory names, so I cannot use "-r" option to process all sub folders named "top".
Thus I built the following windows batch script:


@echo off
call :processImageDirs
goto :eof

:exiftool
exiftool -d %Y-%m-%d-%H-%M-%S%%-c.%%e "-filename<${Make}_${Model}_${DateTimeOriginal}" -execute -o . "-Directory<DateTimeOriginal" -d "M:\Pictures\top\%Y\%Y-%m-%d" -common_args "."

:processImageDirs
for /D %%d in (*) do (
    rem enter image directory
    cd %%d
        rem is there subdir called "top"? => if yes, enter "top" directory
for /D %%d in (*top*) do (
cd %%d
                rem call exiftool
                call :exiftool
                cd ..
        )
        cd ..
)
exit /b


The script traverses all photo directories (named by date) and looks whether there is a subdir called "top".
If yes, then it enters this "top"-directory.
I used some echo statements to print each folder name traversed. This also works fine.

ExifTool invocation within each "top" directory also works fine. But what does not work, is extraction of "DateTimeOriginal" for new filename to be set for the image files.
Camera and model extraction stills works, but for each image I get the same filename:
SONY_DSC-HX400V_
(The pictures I test with, were taken with a Sony DSC HX400V)

Underscore at the end, not date/time extracted and also no file extension.

This is the console output:

Quote
"C:\Users\<my local images dir>\20200504\top"
======== ./DSC05790.jpg
Setting new values from ./DSC05790.jpg
Writing File:FileName
'./DSC05790.jpg' --> './SONY_DSC-HX400V_'
    + FileName = './SONY_DSC-HX400V_'
======== ./DSC05791.jpg
Setting new values from ./DSC05791.jpg
Writing File:FileName
Error: './SONY_DSC-HX400V_' already exists - ./DSC05791.jpg
======== ./DSC05792.jpg
Setting new values from ./DSC05792.jpg
Writing File:FileName
Error: './SONY_DSC-HX400V_' already exists - ./DSC05792.jpg
    1 directories scanned
    1 image files updated
    2 files weren't updated due to errors

Since ExifTool manual invocation within a folder works and Batch traversing also works, currently I don't have any clue how to solve this.

Can someone maybe help me?

Happy Easter and stay safe,
Sascha.

Phil Harvey

Hi Sascha,

To process only folders named "top", add this to your command: -if4 "$directory =~ m(/top$)"

Then run with -r on your root pictures directory.

- Phil
...where DIR is the name of a directory/folder containing the images.  On Mac/Linux/PowerShell, use single quotes (') instead of double quotes (") around arguments containing a dollar sign ($).

Windwalker

Thanks Phil, for your rapid reply.
Great advice by you, so I managed to get rid of this wrapping batch script.

Unfortunately there seems to be some misconception by myself on how to set the filename when renaming.

I simplified my command to
exiftool -d %Y-%m-%d-%H-%M-%S%%-c.%%e "-filename<${Make}_${Model}_${DateTimeOriginal}" -common_args "%CD%" -if4 "$directory =~ m(/top$)"
(this contains just the renaming part)

Again, I am experiencing that the file name, ExifTool computes, only contains Camera manufacturer name and model. Thus, for each of the files processed, only "SONY_DSC-HX400V_" is set as filename (DateTimeOriginal and file extension missing).

If I invoke ExifTool directly from the "top" directory, where the actual images to be processed, are located in, the above command works fine.
But if invoked from the image root directory, DateTimeOriginal are not set.

(maybe take a look at my directory structure, depicted at the initial post on top)

Kind regards,
Sascha.

StarGeek

Are you using a batch file?  If so, double all percent signs (FAQ #27).  Also, since you are using embedded data in your command, you do not want to use -if4, just -if-if4 will only help when you are using the system "pseudo tags", like Directory or Filename.
"It didn't work" isn't helpful. What was the exact command used and the output.
Read FAQ #3 and use that cmd
Please use the Code button for exiftool output

Please include your OS/Exiftool version/filetype

Phil Harvey

-if4 is fine when the -if condition only uses pseudo system tags.  It will speed things up quite a bit if most files fail the condition, but slow things down a bit if most files pass the condition.

I have to find more time to think about your problem to help out with that.  Relaxing and enjoying the Easter holiday right now...

- Phil
...where DIR is the name of a directory/folder containing the images.  On Mac/Linux/PowerShell, use single quotes (') instead of double quotes (") around arguments containing a dollar sign ($).

Phil Harvey

I think StarGeek nailed the problem.  It seems from the "%CD%" that you are using a .bat file, so you need to prevent the .bat processor from mangling the -d argument by doubling all of the "%" characters.

- Phil
...where DIR is the name of a directory/folder containing the images.  On Mac/Linux/PowerShell, use single quotes (') instead of double quotes (") around arguments containing a dollar sign ($).

Windwalker

#6
Phil, following your first reply, I made use of "if4" and was able to get rid of this wrapping batch construction.
The if4-parameter enabled me to only process those subfolders, which are named "top" and contain my selection of best images.

So I simplified the whole invocation. No batch, just the ExifTool command as stated in my second post at https://exiftool.org/forum/index.php?topic=11041.msg59013#msg59013.

But, as described, the problem with missing date still persits.

Kind regards,
Sascha.

Phil Harvey

If there is no batch file, then what is "%CD%" ?   If there is something that expands this to a directory name, then that same thing is killing the % characters in your -d argument.

- Phil
...where DIR is the name of a directory/folder containing the images.  On Mac/Linux/PowerShell, use single quotes (') instead of double quotes (") around arguments containing a dollar sign ($).

Windwalker

You are right, obviously I was a bit confused with all the various attempts I made.
Forget "%CD%".

I did the following:

exiftool -v5 -d %Y-%m-%d-%H-%M-%S%%-c.%%e "-filename<${Make}_${Model}_${DateTimeOriginal}" -r "." -if4 "$directory =~ m(/top$)"


where "." stands for the current invocation directory (my images root dir). I tried with and without option "-r", seems to make no difference.

This is the verbose console output:

Quote
"<images root dir>\05.04.2020\top"
======== ./DSC05790.jpg
Setting new values from ./DSC05790.jpg
Writing File:FileName
'./DSC05790.jpg' --> './SONY_DSC-HX400V_'
    + FileName = './SONY_DSC-HX400V_'
======== ./DSC05791.jpg
Setting new values from ./DSC05791.jpg
Writing File:FileName
Error: './SONY_DSC-HX400V_' already exists - ./DSC05791.jpg
======== ./DSC05792.jpg
Setting new values from ./DSC05792.jpg
Writing File:FileName
Error: './SONY_DSC-HX400V_' already exists - ./DSC05792.jpg
    1 directories scanned
    1 image files updated
    2 files weren't updated due to errors
    1 directories scanned
    2 files failed condition
    0 image files read
    1 directories scanned
    2 files failed condition
    0 image files read
Error: '<images root dir>/05.04.2020/top/SONY_DSC-HX400V_' already exists - <images root dir>/05.04.2020/top/DSC05791.jpg
Error: '<images root dir>/05.04.2020/top/SONY_DSC-HX400V_' already exists - <images root dir>/05.04.2020/top/DSC05792.jpg
    1 directories scanned
    0 image files updated
    2 files weren't updated due to errors

Phil Harvey

Well, I'm just about out of ideas because that command works fine for me on Mac.  Just 2 things to try:

1. Be sure you are using a recent version of ExifTool (current is 11.93).

2. Be sure you are using cmd.exe and not PowerShell.

Also, note that you can set "TestName" instead of "FileName" to make things easier for testing.

- Phil
...where DIR is the name of a directory/folder containing the images.  On Mac/Linux/PowerShell, use single quotes (') instead of double quotes (") around arguments containing a dollar sign ($).

Windwalker

Phil, if it works for you under MacOS... Could I maybe attach one of my folders (I use for testing just one folder with images) with 3 images and you could try it on your machine?

Phil Harvey

Sure.  I'm leaving the computer for a while, but I should be able to try it before tonight.

If you can't attach it, upload somewhere then post a link here.

- Phil
...where DIR is the name of a directory/folder containing the images.  On Mac/Linux/PowerShell, use single quotes (') instead of double quotes (") around arguments containing a dollar sign ($).

Windwalker

Hi Phil,

I just sent you the download link via PM.

Thanks for your effort!
Sascha.

Phil Harvey

Hi Sascha,

It seems to work for me.  I had to change the double quotes to single quotes because I'm on a Mac:

> exiftool -v5 -d %Y-%m-%d-%H-%M-%S%%-c.%%e '-testname<${Make}_${Model}_${DateTimeOriginal}' -r . -if4 '$directory =~ m(/top$)'
======== ./14.03.2020/top/DSC05714.jpg
Setting new values from ./14.03.2020/top/DSC05714.jpg
Writing File:TestName
'./14.03.2020/top/DSC05714.jpg' --> './14.03.2020/top/SONY_DSC-HX400V_2020-03-14-15-31-50.jpg'
======== ./14.03.2020/top/DSC05710.jpg
Setting new values from ./14.03.2020/top/DSC05710.jpg
Writing File:TestName
'./14.03.2020/top/DSC05710.jpg' --> './14.03.2020/top/SONY_DSC-HX400V_2020-03-14-15-16-57.jpg'
======== ./14.03.2020/top/DSC05704.JPG
Setting new values from ./14.03.2020/top/DSC05704.JPG
Writing File:TestName
'./14.03.2020/top/DSC05704.JPG' --> './14.03.2020/top/SONY_DSC-HX400V_2020-03-14-15-05-19.JPG'
-------- ./14.03.2020/DSC05727.JPG (failed condition)
-------- ./14.03.2020/DSC05726.JPG (failed condition)
-------- ./14.03.2020/DSC05714.JPG (failed condition)
-------- ./14.03.2020/DSC05710.JPG (failed condition)
-------- ./14.03.2020/DSC05704.JPG (failed condition)
======== ./05.04.2020/top/DSC05792.jpg
Setting new values from ./05.04.2020/top/DSC05792.jpg
Writing File:TestName
'./05.04.2020/top/DSC05792.jpg' --> './05.04.2020/top/SONY_DSC-HX400V_2020-04-05-16-43-12.jpg'
======== ./05.04.2020/top/DSC05790.JPG
Setting new values from ./05.04.2020/top/DSC05790.JPG
Writing File:TestName
'./05.04.2020/top/DSC05790.JPG' --> './05.04.2020/top/SONY_DSC-HX400V_2020-04-05-16-42-48.JPG'
======== ./05.04.2020/top/DSC05791.jpg
Setting new values from ./05.04.2020/top/DSC05791.jpg
Writing File:TestName
'./05.04.2020/top/DSC05791.jpg' --> './05.04.2020/top/SONY_DSC-HX400V_2020-04-05-16-43-06.jpg'
-------- ./05.04.2020/DSC05803.JPG (failed condition)
-------- ./05.04.2020/DSC05802.JPG (failed condition)
-------- ./05.04.2020/DSC05792.JPG (failed condition)
-------- ./05.04.2020/DSC05790.JPG (failed condition)
-------- ./05.04.2020/DSC05791.JPG (failed condition)
-------- ./05.04.2020/DSC05799.JPG (failed condition)
    5 directories scanned
   11 files failed condition
    0 image files updated
    6 image files unchanged


It should work exactly the same in Windows with double quotes, provided you are using the same ExifTool version and nothing is messing with the % characters in the command.

What do you get for the output of this command, running exactly the same way as the above command?:

exiftool -ver -echo %Y-%m-%d-%H-%M-%S%%-c.%%e

You should get this:

%Y-%m-%d-%H-%M-%S%%-c.%%e
11.93


- Phil
...where DIR is the name of a directory/folder containing the images.  On Mac/Linux/PowerShell, use single quotes (') instead of double quotes (") around arguments containing a dollar sign ($).

Windwalker

Phil, many thanks.

Indeed, this is exactly, what I get, when executing your command:
%Y-%m-%d-%H-%M-%S%%-c.%%e
11.93


I don't have a Mac at hand, but I can try installing ExifTool on Linux.
I will give it a try.

Meanwhile, any hint on how to tackle the problem on windows, of course is welcome.

Sascha.