Convert year-month-day to weekday in file name

datefilenamesrename

I need to take the following filename structure and rename to the appropriate day of the week:

GMT20161003-randomtext.mp4

would end up as monday.mp4

I have a lot of these files in various subdirectories so it would be better if it could be run recursively…

Best Answer

With zsh:

zmodload zsh/datetime
autoload zmv
zmv -n '(**/)GMT(<->)*(.mp4)(#qD.)' '$1${(L)$(
  strftime %A "$(strftime -r %Y%m%d $2)")}$3'

Remove the -n to actually do the renaming.

  • <-> matches any decimal number.
  • That second (...) is captured in $2, (.mp4) in $3 and the directory ((**/), recursive) in $1.
  • (#qD.) is a glob qualifier that only selects regular files (.: not directories, nor symlinks nor fifos/devices...) and also traverse hidden directories (D for dotfile/dotdir).
  • ${(L)...}: converts the expansion to lower-case.
  • strftime -r %Y%m%d: reverse-strftime (strptime) to convert the date to an epoch time.
  • strftime %A ...: format time for that epoch time with %A being for the full week day. Beware it's locale-dependany. (in a French locale, you'll get the French week day).

On a GNU system, and with the GNU shell (bash), you could do:

find . -name 'GMT*-*.mp4' -type f -exec bash -c '
  for file do
    base=${file##*/}
    date=${base#GMT}
    date=${date%%-*}
    wday=$(date -d "$date" +%A)
    echo mv -i "$file" "${file%/*}/${wday,,}.mp4"
  done' bash {} +

(remove echo to perform the operation).

${var,,} being bash's operator to convert to lower case. date -d being the GNU date way to parse a date (like strftime -r above).

While zmv would check for conflicts before starting renaming any file, this one wouldn't. So we add a -i above to at least give you a chance of avoiding clobbering files. GNU mv has a -v option to tell it to show what it's going to do which may be useful to revert the command later if anything went wrong.

Related Question