#1 Le 26/12/2007, à 20:45
- skt310
[resolu][shell] parcours recursif de répertoires
Bonjour. J'ai voulu me faire un script qui renome tous les fichier en minuscules récursivement à partir du dossier passé en paramètre.
J'ai réussi à faire la fonction pour renommer sans majuscules:
#!/bin/sh
IFS="
"
toLowerCase()
{
rename "y/A-Z/a-z/" "$1"
}
Mais je n'ai aucune idée de comment effectuer un parcours récursif des dossiers en appelant cette fonction pour chaque fichier. Si quelqu'un pouvait me donner des indices de la démarche a suivre (ou mieux: un code) je lui en serait reconnaissant.
Dernière modification par skt310 (Le 26/12/2007, à 22:39)
NOVATUX : Besoin d'un ordinateur parfaitement compatible avec linux, un très bon contact avec le vendeur, des conseils, une instalation personalisée. Bref que du bonheur quoi. Allez voir ce site! J'ai acheté mon portable ici et vraiment c'est un plaisir!
Hors ligne
#2 Le 26/12/2007, à 22:04
- pascal50
Re : [resolu][shell] parcours recursif de répertoires
La commande find avec l'action -exec devrait pouvoir faire ça sans utiliser de fonction.
à la place de $1 tu mets '{}' . Cela représente tous les fichiers trouvés par find
le filtre -type f va sélectionner tout les fichiers "normaux" récurcivement à partir du répertoire de départ.
Hors ligne
#3 Le 26/12/2007, à 22:36
- pascal50
Re : [resolu][shell] parcours recursif de répertoires
Mais si tu as plusieurs actions, j'utilise cette boucle :
#! /bin/sh
REP_SOURCE="mon_repertoire_source"
find ${REP_SOURCE} -type f | while read A ; do
echo $A
done
C'est un exemple qui ne fait que "echo $A", mais tu mettre ce que tu veux (les fichiers listés vont tour à tour se retrouver dans la variable A
Hors ligne
#4 Le 26/12/2007, à 22:39
- skt310
Re : [resolu][shell] parcours recursif de répertoires
Merci beacoup!
je préfère la deuxième méthode.
NOVATUX : Besoin d'un ordinateur parfaitement compatible avec linux, un très bon contact avec le vendeur, des conseils, une instalation personalisée. Bref que du bonheur quoi. Allez voir ce site! J'ai acheté mon portable ici et vraiment c'est un plaisir!
Hors ligne
#5 Le 27/12/2007, à 09:30
- skt310
Re : [resolu][shell] parcours recursif de répertoires
Finallement je l'ai fait en python.
Voici le code
#!/usr/bin/python
import os
import sys
def rrename(dir):
tree = os.walk(dir)
for directory in tree:
os.chdir(directory[0])
for file in directory[2]:
new_name = file.lower()
new_name = new_name[0].upper()+new_name[1:]
os.rename(file,new_name)
if sys.argv[1] == "-h":
print """Ce programme permet de renommer recursivement tous les noms de fichier.
UTILISATION: rrename [option] [directory]
OPTIONS: -h \t Affiche l'aide"""
else:
rrename(sys.argv[1])
NOVATUX : Besoin d'un ordinateur parfaitement compatible avec linux, un très bon contact avec le vendeur, des conseils, une instalation personalisée. Bref que du bonheur quoi. Allez voir ce site! J'ai acheté mon portable ici et vraiment c'est un plaisir!
Hors ligne
#6 Le 27/12/2007, à 09:52
- pascal50
Re : [resolu][shell] parcours recursif de répertoires
j'en était là :
#! /bin/sh
REP_SOURCE="/home/pascal/bin/essai2"
find ${REP_SOURCE} -type f | while read A ; do
echo "========================================"
echo $A
CHEMIN=${A%\/*}
echo "CHEMIN = ${CHEMIN}"
FICHIER=${A##*\/}
echo "FICHIER = ${FICHIER}"
modif1=$(echo ${FICHIER} | sed -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/')
modif2=$(echo ${FICHIER} | tr a-z A-Z)
# echo $FICHIER | sed -e "y/a-z/A-Z/" # ne change que les a en A !
echo "modif1 = $modif1"
echo "modif2 = $modif1"
echo "========================================"
done
1) pour les essais je fais le contraire (minuscule -> majuscules) car je n'ai pas de de majuxcules dans mes noms de fichiers
2) je n'ai pas testé les accents, ni les espaces dans les noms de fichiers ni dans les chemins
3) il ne reste qu'a faire un "mv"
mv ${CHEMIN}/${FICHIER} ${CHEMIN}/${modif1}
4) je ne sait pas commment la commande rename agit sur un nom qui comprend un nom de repertoire
+nom fichier (je ne l'ai jamais utilisée dans une arborescence, toujours dans le répertoire courant)
Je ne sais pas ce qui pourrait se passer si le script commence à changer un nom de répertoire pendant le parcours avec find !
Hors ligne
#7 Le 28/12/2007, à 08:58
- skt310
Re : [resolu][shell] parcours recursif de répertoires
sed -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/
Il n'y a pas moyen d'utiliser une classe de regex? (par ex [a-z]/[A-Z] ?
J'ai testé ton script, ça marche mais c'est 50 fois plus rapide en pyhon.
NOVATUX : Besoin d'un ordinateur parfaitement compatible avec linux, un très bon contact avec le vendeur, des conseils, une instalation personalisée. Bref que du bonheur quoi. Allez voir ce site! J'ai acheté mon portable ici et vraiment c'est un plaisir!
Hors ligne
#8 Le 28/12/2007, à 14:32
- aleph
Re : [resolu][shell] parcours recursif de répertoires
> skt310
> j'ai testé ton script, ça marche mais c'est 50 fois plus rapide en pyhon.
Il y a ici plusieurs facteurs qui jouent un rôle.
1) L'utilisation de bash n'est pas toujours faite à bon escient.
2) Sans autres commentaires détaillés, la capacité de Python à pouvoir effectuer certaines tâches très proches du système, particulièrement vrai pour les modules os ou os.stat.
Cela dit, le script proposé n'est pas des meilleurs non plus. Il ne fonctionne pas, par ex sur win32.
A noter accessoirement que les méthodes lower() ou upper() ne s'appliquent que dans le monde ascii.
Ci dessous, une version plus générique pour qui veut effectuer des tâches avec / sur des fichiers.
#-*- coding: iso-8859-1 -*-
#--------------------------------------------------------------
# filesjob.py
# Python 2.5.1
# 28 December 2007
#--------------------------------------------------------------
import os.path
import time
import shutil
#--------------------------------------------------------------
# fn: filename == full path
# various job examples
def dojob(fn):
#print file name
print 'fn:', fn
#split path and filename
#~ pa, sfn = os.path.split(fn)
#~ print pa, sfn
#return the time of last modification of path, in second from epoch
#~ print os.path.getmtime(fn)
#print only filenames starting with a "p"
#~ pa, sfn = os.path.split(fn)
#~ if sfn.startswith('p'):
#~ fullname = os.path.join(pa, sfn)
#~ print fullname
#copy the file onto an exsisting destination directory called destdir
#uses the module shutil
#~ destdir = 'blablabla'
#~ shutil.copy(fn, destdir)
#--------------------------------------------------------------
def visiting():
topdir = 'c:\\temp'
r = []
#parse topdir and save filenames in r
#do this only once
for root, dirs, files in os.walk(topdir):
for fn in files:
r.append(os.path.join(root, fn))
#apply a job for each file
for fn in r:
dojob(fn)
#--------------------------------------------------------------
if __name__ == '__main__':
visiting()
#9 Le 29/12/2007, à 08:43
- skt310
Re : [resolu][shell] parcours recursif de répertoires
@aleph: Qu'est-ce qui ne marche pas dans mon code sous windows (je l'ai pas donc je peut pas tester).
NOVATUX : Besoin d'un ordinateur parfaitement compatible avec linux, un très bon contact avec le vendeur, des conseils, une instalation personalisée. Bref que du bonheur quoi. Allez voir ce site! J'ai acheté mon portable ici et vraiment c'est un plaisir!
Hors ligne
#10 Le 29/12/2007, à 11:12
- aleph
Re : [resolu][shell] parcours recursif de répertoires
> skt310
Bonne nouvelle. J'ai testé à nouveau ta fonction rrename, elle fonctionne très bien. (Lors d'un premier et *trop rapide* test, j'avais eu un problème avec os.py. Trop de b* dans mon script de test). Mea culpa de ce côté.
Cela dit, la façon de parcourir les fichiers/dossiers proposée dans mon script est un peu meilleure. Non pas parce que c'est moi qui l'ai écrite, elle est plus conforme à ce que propose Python (voir Python manual 14.1.4 Files and Directories).
Explication : os.walk() étant un genre "d'itérateur intégré". Il n'est pas nécessaire de faire usage d'un os.chdir(). C'est même déconseillé dans certains cas.
La doc mentionnée plus haut donne des très bons exemples de code pour l'utilisation d'os.walk().
#11 Le 30/12/2007, à 00:24
- Alain.g
Re : [resolu][shell] parcours recursif de répertoires
salut
On peut utiliser convmv pour cela.
Exemple :
convmv -r --lower --notest *
-r : recursif
--lower : en minuscule
--notest : l'enlever pour voir avant ce que ça va donner
Xubuntu Karmic !
Hors ligne