Donc, disons, j'ai un directory avec un tas de files comme g.txt, où g.txt a été modifié pour la dernière fois, disons, le 20 juin 2012.
Comment renommerais-je par lots tous les files (comme g.txt) avec la date de dernière modification du 20 juin 2012 ajoutée à la fin?
Bash simple et rapide pour renommer tous les files (globbed) dans le directory courant de filename.txt
à filename.txt-20120620
:
for f in *; do mv -- "$f" "$f-$(stat -c %Y "$f" | date +%Y%m%d)"; done
Je suis sûr qu'un nerd entreprenant de Bash finda un truc de bord pour le briser. 🙂
Évidemment, cela ne fait pas de choses désirables comme vérifier si un file a déjà quelque chose qui ressemble à une date à la fin.
voici une version du one-liner de goldschrafe qui:
gère également les noms de files commençant par un tiret
for f in *; do mv -- "$f" "$f-$(date -r "$f" +%Y%m%d)"; done
Obligatoire zsh one-liner (sans countr le chargement ponctuel des composants optionnels):
zmodload zsh/stat autoload -U zmv zmv -n '(*)' '$1-$(stat -F %Y%m%d +mtime -- $1)'
Nous utilisons la stat
embeddede dans le module zsh/stat
et la fonction zmv
pour renommer les files. Et voici un extra qui place la date avant l'extension, le cas échéant.
zmv -n '(*)' '$1:r-$(stat -F %Y%m%d +mtime -- $1)${${1:e}:+.$1:e}'
Comme je l'ai compris, nous ne soaps pas à l'avance quelle est la date de modification. Nous devons donc l'get à partir de chaque file, formater la sortie et renommer chaque file de manière à inclure la date de modification dans les noms de files.
Vous pouvez save ce script comme "modif_date.sh" et le rendre exécutable. Nous l'invoquons avec le directory cible comme argument:
modif_date.sh txt_collection
Où "txt_collection" est le nom du directory où nous avons tous les files que nous voulons renommer.
#!/bin/sh # Override any locale setting to get known month names export LC_ALL=c # First we check for the argument if [ -z "$1" ]; then echo "Usage: $0 directory" exit 1 fi # Here we check if the argument is an absolute or relative path. It works both ways case "${1}" in /*) work_dir=${1};; *) work_dir=${PWD}/${1};; esac # We need a for loop to treat file by file inside our target directory for i in *; do # If the modification date is in the same year, "ls -l" shows us the timestamp. # So in this case we use our current year. test_year=`ls -Ggl "${work_dir}/${i}" | awk '{ print $6 }'` case ${test_year} in *:*) modif_year=`date '+%Y'` ;; *) modif_year=${test_year} ;; esac # The month output from "ls -l" is in short names. We convert it to numbers. name_month=`ls -Ggl "${work_dir}/${i}" | awk '{ print $4 }'` case ${name_month} in Jan) num_month=01 ;; Feb) num_month=02 ;; Mar) num_month=03 ;; Apr) num_month=04 ;; May) num_month=05 ;; Jun) num_month=06 ;; Jul) num_month=07 ;; Aug) num_month=08 ;; Sep) num_month=09 ;; Oct) num_month=10 ;; Nov) num_month=11 ;; Dec) num_month=12 ;; *) echo "ERROR!"; exit 1 ;; esac # Here is the date we will use for each file modif_date=`ls -Ggl "${work_dir}/${i}" | awk '{ print $5 }'`${num_month}${modif_year} # And finally, here we actually rename each file to include # the last modification date as part of the filename. mv "${work_dir}/${i}" "${work_dir}/${i}-${modif_date}" done