J'ai une structure de fichiers comme celle-ci:
Il y a donc des dossiers avec des noms à 8 chiffres contenant un ou plusieurs fichiers avec un nom commençant par des nombres à 8 chiffres. Mais ces noms de fichiers sont – disons – hors synchronisation. Alors, j'essaie de les renommer récursivement en bash pour archiver:
Mon script ressemble à:
#! /bin/bash find * -maxdepth 1 -name "*" -type d | while read -r dir do rename 's/$dir\/[0-9]{8}/$dir/' * done
Mais cela ne fonctionne pas et donne des erreurs comme
Le symbole global "$ dir" nécessite un nom de package explicite à (eval 1) ligne 1.
Comment puis-je l'écrire pour renommer les fichiers en fonction de leur nom de dossier?
Merci pour l'aide!
À partir d'une autre réponse, j'ai appris que je dois utiliser
rename "s/$dir\/[0-9]{8}/$dir\/$dir/" $dir/*
Juste au cas où quelqu'un aurait le même problème …
Je n'aime pas vraiment la réponse où $dir
est interpolé dans le motif. Cela pourrait conduire à des résultats inattendus si le répertoire contenait par exemple un caractère qui est interprété comme un jeton regexp spécial.
Je préférerais combiner les fichiers directement dans le modèle, en annulant la nécessité de boucler les répertoires et d'utiliser un glob normal.
rename 's#([^/]+)/[^/]+(\.file[0-9]+)$#$1/$1$2#' base_directory/*/*
Où le glob obtient les fichiers individuels dans les répertoires (il pourrait même être spécifié dans base_directory/*/*.file*
, ou similaire, mais cela ne devrait pas être important ici).
Notez que c'est la commande complète, sans avoir besoin de find
construction.
#
comme séparateur au lieu du "régulier" /
pour éviter d'avoir à échapper à celui dans les motifs. J'ai choisi d'utiliser une approche plus générale que de supposer que les fichiers étaient tous de 8 caractères, mais la différence réelle est que je n'ai pas besoin de find
construction ni de créer la variable $dir
dans l'environnement de regexp (éventuellement dangereux).