I would like to add the time of the last change to the file to its filename using the bash.

For example this output of ls -la:

 -rw-rw-r-- 1 beginner beginner 5382 Dec  1 17:18 B_F1-1.xml

should become

 -rw-rw-r-- 1 beginner beginner 5382 Dec  1 17:18 B_F1-1_20141201T1718.xml

How could I do this to all files in .?

  • How did you get 20141201T1718? – αғsнιη Dec 1 '14 at 16:42
  • @KasiyA It is from the timestamp that the file has in the system: 'Dec 1 -> 2014 12 01' and then T followed by the time 17:18. – Beginner Dec 1 '14 at 16:46
  • @KasiyA its the time stamp of the file, see the output of ls -la in the question. – Beginner Dec 1 '14 at 17:08
  • Sounds like a use case for version control. – Faheem Mitha Nov 6 '15 at 9:30

You can try something like:


mv "$FILE" "$NAME$(date --reference "$FILE" '+%Y%m%dT%H%M').$EXT"

in a script, if your date supports --reference, which picks up the last modification date of the reference file.

  • thanks! this works if I removoe the ' ' around $FILE in the date function. – Beginner Dec 1 '14 at 17:05
  • @Beginner Indeed. My mistake, I think I confused the quoting. – muru Dec 1 '14 at 17:08
  • 5
    You should still use double quotes within "$( ... "$var" ...)" -- the command substitution spawns a subshell so the "inner" quotes do not clash with the "outer" ones – glenn jackman Dec 1 '14 at 17:18
  • @glennjackman I was looking up the quoting rules for command substitution, if that's the correct way, thanks. – muru Dec 1 '14 at 17:19

I think this could work:

for i in *; do 
   fileTime=$(stat -c %Y "$i");  #Get last modification (since EPOCH)
   formatDate=$(date +%Y%m%dT%H%m -d @"$fileTime"); #Get time in format YYYYMMDDTHHmm
   mv "${i%%.*}"_"$formatDate"."${i#*.}"; #Appends "formatDate" before extension


  • I posted wrong minute parameter. It must be capital M (%M), instead of %m (which means month). – Albert Dec 1 '14 at 16:56
  • thank you. One small issue is that the result is filename.xml_formatdate – Beginner Dec 1 '14 at 16:58
  • You are right. Look at muru sample and modify mv "$i" "$i"_"$formatDate"to mv "$i" "${i%%.*}"_"$formatDate"."${i#*.}". Sorry ;) – Albert Dec 1 '14 at 17:05

This can all be done as a oneliner.

for i in *.* ; do mv "$i" "${i%.*}_$(date --reference "$i" +%Y%m%dT%H%M).${i##*.}"; done

For a literal timestamp, i.e., seconds since the epoch, you can just use:

for i in *.* ; do mv "$i" "${i%.*}_$(date --reference "$i" +%s).${i##*.}"; done

This has a safety check to only operate on files whose names contain dots; it correctly handles files with spaces in the names; and it assumes (as would usually be the case) that the LAST dot separated field is the extension, rather than the FIRST dot separated field being the filename and the rest being an extension.

Credit to muru for the --reference bit; I didn't know about that option.

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.