2010-11-24 4 views
3

Je tente de renommer tous les répertoires et fichiers en majuscules avec un script shell. Ce que j'ai fonctionne, mais pas pour les sous-répertoires. Comme les noms de répertoires changent pendant l'exécution des scripts, je reçois des choses comme mv: cannot stat './def/two/three': No such file or directoryUNIX renommer les fichiers/répertoires en majuscules

J'ai essayé d'utiliser -depth avec find afin de le renommer de bas en haut. Mais toujours courir dans le même problème. Je pensais à utiliser cut pour briser le chemin sur / et renommer de cette façon, mais je suis à perte.

Voici ce que j'ai:

for i in `find . -name "*[a-z]*"` 
    do new_name=`echo $i | tr '[a-z]' '[A-Z]'` 
    mv $i $new_name 
done 

Je vous serais reconnaissant toute direction que je me sens comme cela devrait être une tâche commune, mais n'a pas réussi à trouver une solution de travail de quelques recherches Google.

Veuillez noter que je ne peux pas utiliser rename car il n'est pas pris en charge par ma distribution.

+0

Je propose de passer à SuperUser. – Teddy

+1

Si vous avez Perl, 'renommer 'est un script Perl extrêmement simple. Vous pouvez l'utiliser à la place du binaire (qui n'est pas aussi puissant). Il y a des dizaines de questions sur SO concernant le renommage des fichiers et des répertoires et même quelques-uns sur le faire [profondeur d'abord] (http://stackoverflow.com/search?q=%2Brename+%2Bdepth). –

+0

duplication possible de [Comment renommer tous les dossiers et fichiers en minuscules sous Linux?] (Http://stackoverflow.com/questions/152514/how-to-rename-all-folders-and-files-to-lowercase-on -linux) –

Répondre

8

Essayez de cette façon:

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 

ou, si vous voulez que le lisible v ersion (pas un liner):

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 

Cela renommer les fichiers avant, puis le répertoire ils sont, dans l'ordre approprié.

+0

Vous devez indiquer * tout * $ (FOO) et $ FOO comme "$ (FOO)" et "$ FOO". – Teddy

+0

@Teddy: tu as raison, j'avais 2 $ de long qui avait besoin d'être cité. C'est corrigé maintenant. Je ne pense pas en avoir manqué. – Baramin

+0

Cela fonctionne. Notez que si les correspondances '$ LONG' et' $ {DIR}/$ {SHORT} ',' mv' va lancer une erreur. Pour les futurs stumblers, l'ajout d'un contrôle de comparaison résoudrait ce problème. –

0

permet de dire que vous avez cette structure de répertoire
/somewhere/somethimg/
/somewhere/somethimg/dir1
/somewhere/somethimg/dir1/dir2

Je pense que vous devriez commencer le changement de nom avec dir2 puis aller à dir1 et ainsi de suite

+0

Ce serait une première recherche approfondie, qui n'a pas fonctionné comme indiqué dans ma question. –

0

Ce script doit renommer tous les fichiers/répertoires du chemin courant dans le premier ordre «feuille» pour que les choses fonctionnent.

#!/bin/bash 

IFS=$'\n'; 
TMP=/tmp/file_list 
rm -f ${TMP}; 

for file in `find .` 
do 
num=`echo $file | grep -o "/" | wc -l`; 
echo "$num $file" >> ${TMP}; 
done 

sort -n -r ${TMP} | cut -f 2 -d ' ' > ${TEMP}.temp; 

for file in `cat ${TEMP}.temp` 
do 
echo $file; 
## Code to rename file here. All subdirectories would already have been renamed 
done 
+0

+1 pour l'exemple supplémentaire. Je ne l'ai pas testé complètement, mais cela semble fonctionner. Vous devez cependant changer $ TEMP en $ TMP. –

+0

Cela va étouffer les noms de fichiers contenant des caractères spéciaux (espace, '\ [*?'). Il n'est également pas prêt pour la production en raison de l'utilisation non sécurisée d'un fichier temporaire. Pour commencer, utilisez toujours des guillemets autour des substitutions de variables ('$ var') et des substitutions de commandes (' \ 'command \' '). Utilisez 'find -exec', c'est pour ça. L'étape de tri est inutile, lisez sur 'find -depth'. – Gilles

+0

Yup, ne connaissait pas l'option -depth. –

Questions connexes