News:

2023-03-15 Major improvements to the new Geolocation feature

Main Menu

Can one change the value of FileName for %f

Started by saulwold, July 10, 2020, 08:05:08 PM

Previous topic - Next topic

saulwold


Hi There,

I am trying to preserve the FileName during my rename process to add a DateTime Stamp.  I have a massive number of files to handle and I am trying to do some de-duplication as well. I am using exiftool embedded inside a shell script to help with this.

exiftool -P '-Filename<${filemodifydate}00FM%-.2c.%le' '-Filename<${modifydate}00MD%-.2c.%le' '-Filename<${datetimeoriginal}00%-.2c.%le' '-Filename<${datetimeoriginal}${SubSecTimeOriginal}%-.2c.%le' -d /srv/sdh/Ptest2/processed/%Y/%m/%d/%%uf_%Y%m%dT%H%M%S -ext JPG -ext CR2 -ext ORF -ext MOV -ext AVI -ext MPG -ext DNG -ext PNG -ext TIF -ext BMP -ext PDD -ext PDF -ext TXT -ext SDW -ext LIST -r $1

I want to use a a clean'ed up filename (no spaces, convert special characters), kind of like how some people convert/cleanup the Camera Model.  I did try adding a ${BaseName} to the -Filename<${BaseName}...  What I got was a directory named by the value ${BaseName}. Maybe I need to do this all in perl somehow, but it's been a while since I have written perl code!

I know FileName comes from the filesystem, and I want to preserve it in the new filename with date stamp.

I hope I am making myself clear

Thanks
   Sau!

StarGeek

Make sure that your config file has a dot at the beginning, e.g. .ExifTool_config, and is in the same directory as the exiftool program.  Otherwise the BaseName won't be available to use.

You can do some minor editing of the %f variable, such as trimming leading/trailing characters or taking a substring (see the -w (textout) option for details), but for major editing, such as replacements, you'll need to use the Basename tag and the advanced formatting feature.  As an example, to convert any spaces in the filename to underscores, you would use ${BaseName;s/ /_/g} at the appropriate place in your command.
* Did you read FAQ #3 and use the command listed there?
* Please use the Code button for exiftool code/output.
 
* Please include your OS, Exiftool version, and type of file you're processing (MP4, JPG, etc).

saulwold

Quote from: StarGeek on July 10, 2020, 08:32:47 PM
Make sure that your config file has a dot at the beginning, e.g. .ExifTool_config, and is in the same directory as the exiftool program.  Otherwise the BaseName won't be available to use.
Yes of course the Exiftool_config file has a dot in my home directory, this was a copy, sorry that was not clear.

You can do some minor editing of the %f variable, such as trimming leading/trailing characters or taking a substring (see the -w (textout) option for details), but for major editing, such as replacements, you'll need to use the Basename tag and the advanced formatting feature.  As an example, to convert any spaces in the filename to underscores, you would use ${BaseName;s/ /_/g} at the appropriate place in your command.
I am still not clear where I use ${BaseName}, as I said when I put it in the -filename< option, it not not work as expected, here is a more detailed example:

Here I have simplified my command line and showed a couple of examples, the first one worked with no preceding directory and the second with a "processed" directory.

$ ls
untitled_0991-8719 (1).jpg'   untitled_0991-8719.jpg
$ exiftool -P '-Filename<${BaseName}_${datetimeoriginal}00%-.2c.%le' -d %Y%m%dT%H%M%S *.jpg
    2 image files updated
$ ls
'untitled-0991-8719-(1)_20141117T20293200-00.jpg'   untitled-0991-8719_20141117T20293200-00.jpg

example 2: with ./processed in the -d option
$ exiftool -P '-Filename<${BaseName}_${datetimeoriginal}00%-.2c.%le' -d ./processed/%Y%m%dT%H%M%S *.jpg
    2 directories created
    2 image files updated
$ tree
.
├── untitled-0991-8719_.
│   └── processed
│       └── 20141117T20293200-00.jpg
└── untitled-0991-8719-(1)_.
    └── processed
        └── 20141117T20293200-00.jpg

4 directories, 2 files
$


I want everything to land in the processed directory.

hope that helps to clarify the issue.

Sau!

StarGeek

Remove ./processed/ from the -d format string and place it where you want in the tag copy.  Remember, the -d format string completely replaces any date tags, so don't put a directory there if you don't want a subdirectory in that position.

exiftool -P '-Filename<./processed/${BaseName}_${datetimeoriginal}00%-.2c.%le' -d %Y%m%dT%H%M%S *.jpg
* Did you read FAQ #3 and use the command listed there?
* Please use the Code button for exiftool code/output.
 
* Please include your OS, Exiftool version, and type of file you're processing (MP4, JPG, etc).

saulwold

Quote from: StarGeek on July 10, 2020, 08:56:18 PM
Remove ./processed/ from the -d format string and place it where you want in the tag copy.  Remember, the -d format string completely replaces any date tags, so don't put a directory there if you don't want a subdirectory in that position.

exiftool -P '-Filename<./processed/${BaseName}_${datetimeoriginal}00%-.2c.%le' -d %Y%m%dT%H%M%S *.jpg

Ok, I guess I over simplified my example, if you recall I also had the %Y//%m/%d/ prefix as well in the -d and when that is added back in I get the following:

└── processed
    ├── untitled-0991-8719-(1)_2014
    │   └── 11
    │       └── 17
    │           └── 20141117T20293200-00.jpg
    └── untitled-0991-8719_2014
        └── 11
            └── 17
                └── 20141117T20293200-00.jpg


It's getting closer!

Also since I have 4 different -filename< lines I have to edit all for, is there a better way via the .Exiftool_config file to create a timestamp that I can use for 1 -filename entry?

Thanks for your amazingly fast response time!  Do you guys use IRC, slack or some other messaging tool that I can touch base with folks?  Or just this forum?

Sau!

StarGeek

Use the -d (dateFormat) option for whichever timestamp is the most important, use the DateFmt helper function for any other time stamp.  So using your example of %Y/%m/%d/, where ever you want that, use
${DateTimeOriginal;DateFmt("%Y/%m/%d/")}

Quote from: saulwold on July 10, 2020, 09:22:47 PM
Also since I have 4 different -filename< lines I have to edit all for, is there a better way via the .Exiftool_config file to create a timestamp that I can use for 1 -filename entry?

Yes, if it's getting really complex, you can create your own tag to create the whole file path.  Look through the example.config file and search on User Defined tags on this forum for examples to work off of.  It just takes a little Perl coding.  Most of my stuff started off by searching for code snippets from the various StackExchange websites and smacking the keyboard with my head until I got it to work :D

QuoteThanks for your amazingly fast response time!  Do you guys use IRC, slack or some other messaging tool that I can touch base with folks?  Or just this forum?

No messaging tool on my end.  When I'm working at my computer I tend to check the forums every 20-30 minutes.  I also have several of the subforums set to "Notify" (see upper right of any thread or forum) so I'll see new stuff and answer it if I can.  But when it gets to evening (like it is now for me), I'll be doing other things and won't check again until just before I head to bed.
* Did you read FAQ #3 and use the command listed there?
* Please use the Code button for exiftool code/output.
 
* Please include your OS, Exiftool version, and type of file you're processing (MP4, JPG, etc).

saulwold


I think I got it figured out.  Here is what I put into my .Exiftool_config to create a custom Date based filename that I can extend.

Thanks for pointing me in the right direction.

I used it as follows now: exiftool -P '-filename</path/to/processed/${dirandimagename}%-.2c.$le' -r <DIR>

Thanks again for your help!

Sau!


        # Formated Basename with no spaces or special characters
        BaseName => {
            Require => 'FileName',
            ValueConv => q{
                my $fname = $val[0];
                $fname =~ s/\.[^.]+$//;
                $fname =~ s/[^[:print:]]+//g;
                $fname =~ tr{_ /:}{----};
                return $fname;
            }
        },

        # Directory and Image Name Prefix
        DirAndImageName => {
            ValueConv => sub {
                my $exiftool = pop;
                $basename = $exiftool->GetInfo('BaseName');
                $basename = $$basename{'BaseName'};
                $isodate = $exiftool->GetInfo('ISODate');
                $isodate = $$isodate{'ISODate'};
                my $fmtParse = "%Y%m%dT%H%M%S";
                $dt = Time::Piece->strptime($isodate, $fmtParse);
                my $fmt = "%Y/%m/%d";
                $dirdate = $dt->strftime($fmt);
                return "${dirdate}/${isodate}_${basename}";
            }
        },

        # Formatted Date
        ISODate => {
            ValueConv => sub {
                use Time::Piece;
                @datetags = qw( DateTimeOriginal CreateDate ModifyDate FileModifyDate );
                @suffixlist = ( '', '', 'MD', 'FM' );
                my $exiftool = pop;
                my $suffix = '';

                my $i = 0;
                foreach $tag (@datetags) {
                    $val = $exiftool->GetInfo($tag);
                    $val = $$val{$tag};
                    $suffix = $suffixlist[$i++];
                    next if ( $val !~ /^\d{4}:/ || $val =~ /^0000:/ );
                    last if ( $val );
                }
                # Prepare date format string
                my $fmtParse = "%Y:%m:%d %H:%M:%S";
                $dt = Time::Piece->strptime($val, $fmtParse);
                my $fmt = "%Y%m%dT%H%M%S";
                $isodate = $dt->strftime($fmt);
                $subsec = $exiftool->GetInfo('SubSecTimeOriginal');
                $subsec = $$subsec{'SubSecTimeOriginal'};
                if ( $subsec ) {
                    return "${isodate}${subsec}${suffix}"
                } else {
                    return "${isodate}00${suffix}";
                }
            }
        },


saulwold


I am back with a question, I did not notice this before, but when I run exiftool alone with not option and my .ExifTool_config, I do not get any output.  I tried to comment out various sections and as far as I can tell the problematic line is in ISODate at $val = $exiftool->GetInfo($tag);  Why would break regular output from exiftool?  Is there some other way to get info?

Thanks
   Sau!



Phil Harvey

For Composite tags, you should Require the tags you want instead of trying to use GetValue() in your ValueConv function.

- 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 ($).

StarGeek

As an example of what Phil said, your DirAndImageName reformatted, (though I haven't tested it, so some tweaking may be required)

# Directory and Image Name Prefix
DirAndImageName => {
Require => {
0 => 'BaseName',
1 => 'ISODate',
},
ValueConv => q {
my $basename = $val[0];
my $isodate = $val[1];
my $fmtParse = "%Y%m%dT%H%M%S";
$dt = Time::Piece->strptime($isodate, $fmtParse);
my $fmt = "%Y/%m/%d";
$dirdate = $dt->strftime($fmt);
return "${dirdate}/${isodate}_${basename}";
}
},
* Did you read FAQ #3 and use the command listed there?
* Please use the Code button for exiftool code/output.
 
* Please include your OS, Exiftool version, and type of file you're processing (MP4, JPG, etc).