[bash] bonne façon de faire une boucle sur un ensemble de fichiers contenu dans un dossier
Le
Francois Lafont
Bonjour à tous,
Assez régulièrement, je suis amené à me faire des petits scripts bash
qui font une boucle sur une liste de fichiers contenus dans un dossier
(et dans ses sous-dossiers etc). La liste de fichiers, qui peut être
assez grande, est obtenue à l'aide de la commande find. Le but est de
faire un même petit traitement sur chacun des fichiers de cette liste
via une boucle (le traitement importe peu ici, ça peut être un
"renommage", un grep etc). La structure de mes petits scripts
ressemblent à ça du coup (c'est un exemple) :
#-
for fichier in $(find /le/dossier/ -type f -iname '*.tex')
do
echo Traitement de $fichier
# etc.
done
#-
Est-ce la bonne façon de procéder ? J'ai des doutes :
1) En effet, finalement le script revient à ça :
#-
for fichier in /le/dossier/f1.tex /le/dossier/f2.tex /le/dossier/f3.tex
do
echo Traitement de $fichier
# etc.
done
#-
Du coup, si la liste est très grande, ça me semble un peu maladroit
comme script et peut-être pas très performant. (Aucune certitude bien
sûr, c'est juste une intuition.)
2) Une autre chose qui me fait penser que ce n'est peut-être pas la
bonne façon de procéder, c'est le problème avec les noms de fichiers qui
contiennent un espace. Si find détecte un fichier qui s'appelle par
exemple "/le/dossier/sous dossier/toto.tex" alors, durant la boucle,
$fichier sera égal à la chaîne "/le/dossier/sous" puis à
"dossier/toto.tex" mais jamais à "/le/dossier/sous dossier/toto.tex".
Bref, quelle est la bonne façon de faire ce genre de boucle ?
Merci d'avance pour votre aide.
--
François Lafont
Assez régulièrement, je suis amené à me faire des petits scripts bash
qui font une boucle sur une liste de fichiers contenus dans un dossier
(et dans ses sous-dossiers etc). La liste de fichiers, qui peut être
assez grande, est obtenue à l'aide de la commande find. Le but est de
faire un même petit traitement sur chacun des fichiers de cette liste
via une boucle (le traitement importe peu ici, ça peut être un
"renommage", un grep etc). La structure de mes petits scripts
ressemblent à ça du coup (c'est un exemple) :
#-
for fichier in $(find /le/dossier/ -type f -iname '*.tex')
do
echo Traitement de $fichier
# etc.
done
#-
Est-ce la bonne façon de procéder ? J'ai des doutes :
1) En effet, finalement le script revient à ça :
#-
for fichier in /le/dossier/f1.tex /le/dossier/f2.tex /le/dossier/f3.tex
do
echo Traitement de $fichier
# etc.
done
#-
Du coup, si la liste est très grande, ça me semble un peu maladroit
comme script et peut-être pas très performant. (Aucune certitude bien
sûr, c'est juste une intuition.)
2) Une autre chose qui me fait penser que ce n'est peut-être pas la
bonne façon de procéder, c'est le problème avec les noms de fichiers qui
contiennent un espace. Si find détecte un fichier qui s'appelle par
exemple "/le/dossier/sous dossier/toto.tex" alors, durant la boucle,
$fichier sera égal à la chaîne "/le/dossier/sous" puis à
"dossier/toto.tex" mais jamais à "/le/dossier/sous dossier/toto.tex".
Bref, quelle est la bonne façon de faire ce genre de boucle ?
Merci d'avance pour votre aide.
--
François Lafont

Poser une question


fr.comp.os.linux.configuration :
Bonjour,
Je ne suis pas spécialiste mais je pense que tu peux jetter un oeil à
l'option -exec de find.
D'autres options de manipulation de fichier existent également
(-delete par ex).
man find
--
Doug - Linux user #307925 - Slackware64 roulaize ;-)
http://www.dougwise.org
http://usenet-fr.dougwise.org
http://news.dougwise.org
Hash: SHA1
Le 22/05/2011 18:27, Francois Lafont a écrit :
find /le/dossier/ -type f -iname '*.tex' | while read FILE; do
echo "${FILE}"
done
- --
Aeris
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.11 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/
iQEcBAEBAgAGBQJN2Ts0AAoJEK8zQvxDY4P938sIAMCNjiya/RT0hJHza5O8r0aN
K3X1iutv+bCYQVm06DeU9toIhIxAh72OAQIxzzmFPycNVC+bUe3QMsCltClcRkhj
PnnswG9m1TfB6AYyUfMt3KkEspzHeDnC6OvYNGRegWe1uO30mePApI9+R7tpYpmz
3u7hIOi51CqmTve8P7xuh67SQYKqwPKkXWYOGscLI7kpaWY5720O4LVH90uCsR3x
7usbUA+C+vENxWTMz1NNmp67MwZoUSWXloYBDAABkJ6QPs38KUoj63KvCym0eRBM
NWE8UeBIQy/GpaGPmlVwhpOdWyc2wwpfCd1UkqOb5LEf67bjJLBmgQmZbk3dqxM =w5K9
-----END PGP SIGNATURE-----
Oui, je connais l'option -exec mais le souci c'est que même si le
traitement sur chaque fichier est assez basique en général, il m'est
souvent difficile de le faire tenir sur une seule ligne. Du coup,
j'avais pensé à faire un truc dans ce genre :
function f(){
echo Traitement de $1
# etc.
}
find /le/dossier/ -type f -exec f {} ;
Mais dans l'option -exec, la fonction f semble totalement inconnue et le
code ne fonctionne pas.
--
François Lafont
Merci bien Aéris, ça m'a l'air parfait. J'aimerais simplement comprendre
la différence entre ${FILE} et $FILE, je ne vois pas trop.
--
François Lafont
Faut exporter la fonction, et lancer un shell dans exec :
export func
find /dossier-type f -exec sh -c 'func $1' _ {} ;
--
XAv
In your pomp and all your glory you're a poorer man than me,
as you lick the boots of death born out of fear.
(Jethro Tull)