changer l'arborescence de répertoires entière en noms minuscules

12

Je travaille sur une conversion de site Web. Les fichiers tels qu'ils étaient liés et servis à partir du serveur Web n'étaient pas sensibles à la casse. Mais, j'ai fait un vidage du site sur mon système Linux et j'écris des scripts pour migrer les données. Le problème est que je rencontre des problèmes de respect de la casse entre les chaînes de liens dans les pages et la casse réelle des mots sur le système de fichiers.

Par exemple, une page peut avoir un lien similaire à celui <a href='/subfolder/PageName.asp'>du fichier réel /subfolder/pagename.asp. De même avec les images - <img src='spacer_sm.gif'>peut-être Spacer_Sm.gif.

Donc, ma pensée est de changer tous les répertoires et noms de fichiers en leurs équivalents minuscules pour le téléchargement du site. Comment puis-je faire cela (et pourrait-il y avoir une meilleure façon?)

Même s'il existe des commandes Unix qui ont des commutateurs insensibles à la casse, j'utilise php, donc toutes les commandes du système de fichiers n'ont pas d'options de sensibilité à la casse.

user394
la source
2
Voir une question précédente similaire . J'ai republié une réponse plus simple ici parce que la question est un peu plus spécifique.
Gilles 'SO- arrête d'être méchant'

Réponses:

8

Je ne sais pas si votre saveur unix a un rename. De nombreux Linux l'ont fait, et il fait partie d'un paquet perl, si vous recherchez un référentiel.

find ./ -depth -exec rename -n 'y/[A-Z]/[a-z]/' {} ";"

Version ci-dessus avec

rename -n 

n'effectue pas vraiment l'action, mais n'imprime que ce qui serait fait. Vous omettez le -n pour le faire pour de vrai.

Utilisateur inconnu
la source
Quelle «langue» ou expression rationnelle est la 'y/[A-Z]/[a-z]/'partie?
user394
Eh bien, puisque renamefait partie d'un perlpackage, je suppose que Perl, mais le modèle est également utilisé sed, et peut-être AWKaussi. Je ne connais sedbien que le calme. Je traduis yen translateou map, mais je ne sais pas d'où vient le personnage.
utilisateur inconnu
Doit être perl regex - Gilles dans sa réponse dit que renamec'est un script perl.
user394
Oui, et vous pouvez utiliser des expressions rationnelles perl, pour modifier les noms de fichiers, ce qui ne conclut pas nécessairement d'être écrit en perl, mais qui pourrait être la question la plus intéressante.
utilisateur inconnu
9

Zsh

zmv -o-i '(**/)(*)' '$1${2:l}'

Explications: zmvrenomme les fichiers correspondant à un modèle en fonction du texte de remplacement donné. -o-ipasse l' -ioption à chaque mvcommande sous le capot (voir ci-dessous). Dans le texte de remplacement, $1, $2, etc, sont les groupes successifs dans le parenthésées modèle. **signifie tous les répertoires (sous) *, récursivement. La finale (/)n'est pas un groupe entre parenthèses mais un qualificatif glob qui signifie ne correspondre qu'aux répertoires. ${2:l}convertit $2en minuscules.

Renommer Perl

Ici, j'utilise le script de changement de nom Perl /usr/bin/prenamefourni par Debian et Ubuntu (généralement également disponible rename). Avec bash ≥4 ou zsh:

shopt -s globstar  # only in bash
rename 's!/([^/]*/?)$!\L/$1!' **/*

Avec d'autres coquilles:

find . -depth -exec rename -n 's!/([^/]*/?)$!\L/$1!' {} +

Portable

Récursivement:

find . -depth -exec sh -c '
    t=${0%/*}/$(printf %s "${0##*/}" | tr "[:upper:]" "[:lower:]");
    [ "$t" = "$0" ] || mv -i "$0" "$t"
' {} \;

L'utilisation de -depthassure que les répertoires profondément imbriqués sont traités avant leurs ancêtres.

Gilles 'SO- arrête d'être méchant'
la source
1

Il n'a pas fonctionné sur la structure de répertoires suivante:

JKL/
deF/
ABC/DEf
ABC/gHi
ghi/jkL

Voici un exemple qui fonctionne:

for i in `find | sort -r | sed '$d'`; do \
   b=${i%/*}; e=${i##*/}; mv $i $b'/'${e,,}; done

Pour une explication sur bet evars:

man bash

Utilisez ensuite la séquence de touches suivante: /,,Enterbb

Baronsed
la source
0

La réponse acceptée n'a pas fonctionné pour moi car elle a essayé de changer tous les répertoires à la fois. J'ai trouvé une autre solution sur stackexchange très similaire à celle portable de Gilles ci-dessus: de Baramin -
/programming/4268591/unix-rename-files-directories-to-uppercase

Je l'ai copié ici:

find . -depth | \
while read LONG; do
   SHORT=$( basename "$LONG" | tr '[:lower:]' '[:upper:]' )
   DIR=$( dirname "$LONG" )
   if [ "${LONG}" != "${DIR}/${SHORT}"  ]; then
     mv "${LONG}" "${DIR}/${SHORT}"
   fi
done

Pour lequel j'ai changé la commande tr en ie: sed s / cat / dog / g

Merci à Baramin au lien ci-dessus.

JJones
la source