6

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 .?

4
  • How did you get 20141201T1718? Commented Dec 1, 2014 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. Commented Dec 1, 2014 at 16:46
  • @KasiyA its the time stamp of the file, see the output of ls -la in the question. Commented Dec 1, 2014 at 17:08
  • Sounds like a use case for version control. Commented Nov 6, 2015 at 9:30

3 Answers 3

6

You can try something like:

EXT=${FILE#*.}
NAME=${FILE%%.*}

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.

4
  • thanks! this works if I removoe the ' ' around $FILE in the date function. Commented Dec 1, 2014 at 17:05
  • @Beginner Indeed. My mistake, I think I confused the quoting. Commented Dec 1, 2014 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 Commented Dec 1, 2014 at 17:18
  • @glennjackman I was looking up the quoting rules for command substitution, if that's the correct way, thanks. Commented Dec 1, 2014 at 17:19
4

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
done

Regards.

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

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.

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.