I'm in a macOS environment.

I'd like to change the time stamp on multiple files that has names that starts with this format:


This is an example of a filename:


Creation and modification date should be change to 16/10/2018 at 10:58:26.

I had the following script for filenames of the form Call@1234567890(1234567890)_20160624205913. It extracts date and time from the end of the file name, as a parameter for touch -t STAMP:

for f in *; do
    t="$(awk '/_.*/ { match($0, /_.*/)
                      print substr($0, RSTART + 1, RLENGTH - 7)
                    }'<<<"$f" )"
    touch -t "$t" "$f" 2>/dev/null
  • I'd like to change the attribute of the file itself. The meta data is necessary to be with date of modify, creation etc. with da information of the file named in that format. – Giancarlo Passaglia Nov 13 '18 at 18:45
  • find . -iname 'XXXX*' | xargs touch – user1133275 Nov 14 '18 at 1:33
  • Try removing the 2>/dev/null to see a useful error message, possibly including the output of the awk step. – JigglyNaga Nov 14 '18 at 14:41
  • this should work, provided that the XXXXX doesn't contain - or _: xtouch(){ (set -f; IFS='_-'; f=$1; set -- $f; touch -t "$4$3$2$5$6.$7" "$f") }; xtouch CALLU_16-10-2018_10-58-26_p123456789012.mp3. I don't have any MacOS to test on, though. – mosvy Nov 14 '18 at 15:08

The old problem

Your old awk script was searching for the first _ in the filename, and then using everything from the next character (RSTART+1) to 6 characters before the end (RLENGTH-7: +1-7 = -6).

On your input filename, that would produce 20160624, ie. just the date, without time-of-day. From the touch specification:

The option-argument shall be a decimal number of the form:


where each two digits represents the following:

 The month of the year [01,12].
 The day of the month [01,31].
 The hour of the day [00,23].
 The minute of the hour [00,59].
 The first two digits of the year (the century).
 The second two digits of the year.
 The second of the minute [00,60]. 

...which would mean, with only 8 digits, the "20" is interpreted as the month, ie. an invalid date. But you wouldn't see touch reporting an error because of the 2>/dev/null.

You would have needed to add 4 more characters (to provide hh and mm), by using eg. RLENGTH-3. But that's only useful on the old filenames.

The new problem

In your filename CALLU_16-10-2018_10-58-26_p123456789012.mp3, the date 16-10-2018 is in little-endian order (DD-MM-CCYY), so your awk script will need to swap the components, as well as removing all the separators:

awk -F '[-_]' '{print $4$3$2$5$6"."$7}'

(If your input filenames contain additional - characters before the date, this will need further steps to extract the parts between the _s first.)

Test this with your example file:

$ echo 'CALLU_16-10-2018_10-58-26_p123456789012.mp3' | awk -F '[-_]' '{print $4$3$2$5$6"."$7}'

So your updated script could look something like:

for f in *.mp3; do
    t=$(echo "$f" | awk -F '[-_]' '{print $4$3$2$5$6"."$7}')
    touch -t "$t" "$f"
  • infact if I use your routine, it produce "out of range or illegal time specification: [[CC]YY]MMDDhhmm[.SS]" – Giancarlo Passaglia Nov 15 '18 at 8:34
  • @GiancarloPassaglia Sorry, what command did you run to see that error message? [[CC]YY]MMDDhhmm[.SS] is the format, not the exact argument. – JigglyNaga Nov 15 '18 at 10:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.