8 votes

Comment remplacer un dossier dont le nom est une date, par exemple YYYYMMDD, par une hiérarchie de dossiers composée de l'année, du mois et de la date ?

J'ai une liste de dossiers dont les noms comportent des dates. Les dates sont au format AAAAMMJJ (par exemple 20150129). Dans ces dossiers se trouvent des documents texte liés à cette date spécifique.

Je voudrais les restructurer dans une hiérarchie de dossiers allant de l'année au mois à la date, et déplacer les documents textuels dans le dossier "date" correspondant plus bas dans la hiérarchie.

En d'autres termes, j'aimerais que le dossier "Racine" soit nommé d'après l'année, par exemple 2015, et qu'il crée ensuite des sous-dossiers nommés d'après les mois, par exemple 01, puis d'autres sous-dossiers nommés d'après les dates, par exemple 29, qui contiennent les documents textuels correspondants.

Le chemin d'accès serait donc le suivant 2015/01/29/file.txt ou 2015>01>29>file.txt .

J'ai jeté un coup d'œil à Automator et il semble que quelque chose comme cela ne soit pas possible, bien que je puisse me tromper, alors j'aimerais savoir...

  1. Existe-t-il une solution simple à ce problème que n'importe quel profane peut comprendre, par exemple un flux de travail Automator, ou cela nécessite-t-il une certaine compréhension des commandes de terminal et des expressions régulières ?

  2. Comment résoudre ce problème, si tant est qu'il existe une solution ?

8voto

grg Points 181593

Vous pouvez utiliser ce qui suit dans Terminal. cd dans le dossier contenant, puis exécutez la commande suivante :

find . -type f -exec bash -c \
  'F=$(sed -E "s#^\./([0-9]{4})([0-9]{2})([0-9]{2})#\1/\2/\3#" <<< $1);\
  mkdir -p -- $(dirname "$F");\
  mv -- "$1" "$F"' - {} \;

find . -type f obtient tous les fichiers du répertoire actuel de manière récursive.
-exec bash -c ouvre un shell pour exécuter les commandes suivantes.
F=$(…) ouvre un sous-shell et utilise sed sur le chemin d'accès au fichier pour manipuler le chemin d'accès aux dossiers.
^\./([0-9]{4})([0-9]{2})([0-9]{2}) est une expression rationnelle comportant trois groupes de capture, comme suit :
\1/\2/\3 est le remplacement, où chaque groupe de capture ( \1 etc.) sont séparés par / .
mkdir -p -- $(dirname "$F") crée les répertoires dans lesquels les fichiers seront déplacés.
mv -- "$1" "$F" déplace chaque fichier dans le dossier correspondant.

Il s'agit de convertir la hiérarchie de gauche en hiérarchie de droite :

 20170201                2017
    abcdefghij              02
 20170302                       01
     abcdefghij 2                   abcdefghij
                                03
                                    02
                                        abcdefghij 2

Si le dossier contient d'autres fichiers dont le nom contient une date, ils seront déplacés comme s'il s'agissait d'un dossier. Pour éviter cela, remplacez la deuxième ligne par :

  'F=$(sed -E "s#^\./([0-9]{4})([0-9]{2})([0-9]{2})(?:/.+)#\1/\2/\3#" <<< $1);\

En (?:/.+) garantit que le chemin d'accès a un composant ultérieur, ignorant ainsi tout ce qui n'a pas d'enfant dans le répertoire parent et qui est un fichier.

8voto

nohillside Points 82672

En supposant que tous ces dossiers YYYYMMDD fassent partie du même répertoire parent, vous pouvez exécuter la commande suivante

cd PARENT_DIRECTORY
for d in */; do
    [[ $d =~ [0-9]{8}/ ]] || continue
    mkdir -p -- "${d:0:4}/${d:4:2}"
    mv -- "$d" "${d:0:4}/${d:4:2}/${d:6:2}"
done
  • En for d in */; do La boucle lit toutes les entrées du répertoire, la ligne de fin / garantit que seuls les noms de répertoires correspondent réellement
  • [[ $d =~ [0-9]{8}/ ]] vérifie si l'entrée actuelle est composée de 8 chiffres et passe à l'entrée suivante si ce n'est pas le cas
  • ${d:0:4}/${d:4:2}/${d:6:2} utilise l'expansion des paramètres au sein de bash pour créer une chaîne de caractères contenant le nouveau chemin
  • En -- dans les deux mkdir y mv évite les problèmes lorsque le nom du répertoire ou du fichier commence par un - . Cela ne peut pas se produire ici, mais c'est probablement une bonne pratique de toute façon.

Merci à @terdon et @user3439894 pour leurs idées sur la façon d'améliorer le script original.

LesApples.com

LesApples est une communauté de Apple où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres utilisateurs d'appareils Apple, poser vos propres questions ou résoudre celles des autres.

Powered by:

X