can i automatically set the timestamp of a file based on part of its filename?

I have a bunch of files (approx. 500) with the same name pattern, that is : name_CreationDate.pdf. For instance: invoice015_2013_06_25.pdf or invitation035_2012_11_30.pdf. The last 10 digits are always the creation date. The original timestamps of the files have been messed up by a batch application which set them all to the same day; therefore they mean nothing anymore.


Is there a way to automatically set the timestamp (for instance the "Creation Date" one) to the date indicated in the filename? I was thinking of Automator or some kind of shareware/freeware. Does anyone of you have an idea about this? Ideally as a batch rather than individually.


Thanks,

mac book pro, Mac OS X (10.6.5)

Posted on Sep 5, 2013 2:17 PM

Reply
17 replies

Sep 5, 2013 4:53 PM in response to lanceloz

Automatically? AFAIK, no. Standard tools for this task? AFAIK, no. A script can be written to do this, however. If you're familiar with bash, then man touch for details. For more information, here's an semi-related example, though it'd have to be hacked heavily to match your particular requirements and your particular filename format. Here's an example that's a little closer to your requirements.

Sep 5, 2013 9:29 PM in response to lanceloz

This works for me on sample files.



#!/bin/bash
#
# process all files with *nnn_YYYY_MM_DD.* format
# Note: Non-current year creation dates do not show time, but Finder
# Get Info will show full creation detail.
for f in "$@"
do
    # strip file extension
    afile=${f%.*}
    #define new separator for filename
    oIFS="$IFS"
    IFS="_"
    # unpack individual filename components in array
    declare -a filedate=($afile)
    IFS="$oIFS"
    unset oIFS
    #printf "%s\n" "${filedate[@]}"
    # Only want the date components
    filedate=("${filedate[@]:1}")
    #printf "%s\n" "${filedate[@]}"
    hhmm=`date "+%H%M"`
    #now concatenate the current time
    filedate=("${filedate[@]}" "${hhmm}")
    # generate date/time string compatible with touch
    tdate=$(printf "%s" "${filedate[@]}")
    #printf "%s\n" $tdate
    # force creation date derived from current filename
    touch -t $tdate $f
    unset filedate
done
exit 0

Sep 6, 2013 12:30 AM in response to VikingOSX

Thank you for your script. I made a test based on your script:


a) I copied a PDF file on my desktop and named it "URSAFF 1er trim 2012_1998_09_19.pdf". The date component I want to set ultimately is therefore 1998_09_19.


b) I created a service in Automator and pasted your script in a "Run a Shell Script" command. I added the Get Specified Finder Items at the beginning to be able to test the script on the file from Automator. (See screen shot of Automator below)


c) The script appears to run successfully but I don't see a change in the timestamps of the file after I display Get Info from the Finder. (See screen shot of Get Info after I run the shell script)


I wonder if my Region settings (I am based in France) do not interfere with the date/time string layout compatible with touch in your script. Just in case, I have added a capture of these settings.User uploaded file


User uploaded file

User uploaded file

Sep 6, 2013 3:34 AM in response to lanceloz

This script was tested with a file format that you originally offered without spaces in the name (e.g. invoice015_2013_06_25.pdf). The file that you ran the script against is “URSAFF 1er trim 2012_1998_09_19.pdf”, and does not match the contiguous name, filennn_YYYY_MM_DD.extension that the script is designed to correctly function. You probably have files named URSAFF, 1er, trim, and 2012_1998_09_19.pdf, all with the Sep 19 1998 date on them.


If I quoted everything but the file extension on your URSAFF file, the script puts the following information into the array:

URSAFF 1er trim 2012

1998

09

19


After I shift the array elements on line 19 (the [@]:1) syntax, the new array contents are:

1998

09

19


The tdate variable contains: 199809190625.


If I change the touch sequence to: touch -t $tdate "${f}"


The file “URSAFF 1er trim 2012_1998_09_19”.pdf is correctly date stamped as Sep 19 1998.


See if changing the Pass input selection to “as arguments” helps too.

Sep 6, 2013 1:09 PM in response to VikingOSX

Ok. Thank you for the explanation. I guess I had assumed that the spaces in the beginning of the filename would not matter. I was thinking that the date would be figured out from right to left. I was not familiar with the array system.


This being said, the script works great with files without spaces. However, I am not sure I understood what to do to successfully run the current script on files with spaces (the majority of them have spaces).


I am unclear with what you mean by "If I I quoted everything but the file extension on your URSAFF file". Are you suggesting that the script would work if I would add quotes ("") to enclose the filename. So a b c_2010_09_19.pdf becomes "a b c_2010_09_19".pdf?


Sorry for the probably newbie questions, but I am not too skilled on scripting.


Sep 6, 2013 1:20 PM in response to lanceloz

bash uses spaces as delimiters for the "hunks" of a command, and thus accepts spaces within filenames or within strings by quoting the string or the filename, or wants the spaces escaped with a \ character.


For this case, that would be either 'a b c_2010_09_19.pdf' or a\ b\ c_2010_09_19.pdf or (yes) a string with an embedded substring that's quoted as in "a b c_2010_09_19".pdf


FWIW, here are some Bash Quoting Rules, and (more generally) Apple has available an introduction to shell scripting. The latter primer is also as a PDF download, with a zip of the code downloaded separately.

Sep 6, 2013 1:20 PM in response to lanceloz

By the way, I was considering another solution.


I do have a Time Machine backup of the folder containing my 500+ files. The backup has the correct timestamps for each file but they have not been processed through the batch application.


Is there an easy way to script the copy of the timestamp of a given file in one folder (say "OldFolder") and paste it onto the same file into another folder (say "NewFolder"). That could maybe be easier?

Sep 7, 2013 10:18 AM in response to VikingOSX

Here is a simplified, but still functional example of my original script. Following MrHoffman's advice on Bash Quoting rules, this script would be run from the Terminal like this:


nameofscript.sh "URSAFF 1er trim 2012_1998_09_19".pdf

nameofscript.sh foo_2009_02_06.py



#!/bin/bash

#

# Process all files with *_YYYY_MM_DD.* format and use the YYYY_MM_DD

# as new creation date. If the input file basename has spaces or other

# characters treated specially by the shell, the basename will require

# single, or double quotes -- either will work with this script.

#


for f in "$@"

do

# return YYYY_MM_DD from filename

justthedate=`echo "${f}" | egrep -o --color=never '([0-9]{4}_[0-9]{2}_[0-9]{2})'`

#define new separator for filename

oIFS="$IFS"

IFS="_"


# split the YYYY_MM_DD string into individual list elements

declare -a filedate=($justthedate)


#restore original separator

IFS="$oIFS"

unset oIFS

#printf "%s\n" "${filedate[@]}"


hhmm=`date "+%H%M"`

#now concatenate the current time into array

filedate+=($hhmm)

# generate date/time string compatible with touch

tdate=$(printf "%s" "${filedate[@]}")

#printf "%s\n" $tdate

# force creation date derived from current filename

touch -t $tdate "${f}"

unset filedate

done

exit 0


Sep 8, 2013 6:48 AM in response to lanceloz

Here's a bash script.


Note: works on file in ~/Desktop Adjust to the directory you need

Note: hours and minutes of file set to 00.00 Adjust accordingly

Note: I only tested on 2 files, so test on copies before use



#/bin/bash

for f in ~/Desktop/*
do
   date=${f#*_}
   date=${date%.*}
      if [[ $date = ????_??_?? ]] 
         then
            date=$( echo $date | /usr/bin/sed 's/_//g' )  
            touch -t ${date}0000 $f
      fi
done

Sep 8, 2013 8:47 AM in response to Tony T1

Shorter than mine. Cool.


The OP may not have files with multiple ‘_’ in the filename before the date sequence. If they exist, my script will correctly process these filenames without change. (e.g. do_foo_2007_06_01.pdf)


Also, for those with Xcode command line tools installed, there is the /usr/bin/getfileinfo and /usr/bin/setfile combination that can (in combination) set new creation date. No man pages though. Info from an older [.} superuser post.

Sep 8, 2013 5:36 PM in response to VikingOSX

VikingOSX wrote:


The OP may not have files with multiple ‘_’ in the filename before the date sequence.


Good point.

This will extract the last 10 chars in the filename (after striping the .ext):


#/bin/bash

for f in ~/Desktop/*
do
   d=${f%.*}
   d=${d:${#d}-10}
   if [[ $d = ????_??_?? ]] ; then
      d=$( echo $d | /usr/bin/sed 's/_//g' )  
      touch -t ${d}0000 $f
   fi
done

This thread has been closed by the system or the community team. You may vote for any posts you find helpful, or search the Community for additional answers.

can i automatically set the timestamp of a file based on part of its filename?

Welcome to Apple Support Community
A forum where Apple customers help each other with their products. Get started with your Apple Account.