Trucs:Travailler sur un ensemble de fichiers

De Lea Linux
(Redirigé depuis Trucs:Oldid=13)
Aller à la navigation Aller à la recherche
Jice<jice chez lea-linux point org>

Remarque : les commandes qui suivent sont à taper sur une seule ligne de commande.

Comment rechercher dans /home/jice (par exemple) tous les fichiers plus récents qu'une date donnée ?
Créez un fichier temporaire (on l'effacera par la suite) à la bonne date par :
touch -t 199912251615 fichier.tmp
(cela crée le fichier fichier.tmp, avec comme date de dernière modif le 25/12/1999 à 16h15).
Ensuite, tapez :
find /home/jice -newer fichier.tmp -print
pour en afficher la liste (voir man find pour les autres options de find).

Comment travailler (copier, renommer, etc.) sur des fichiers de façon globale ?
C'est en même temps moins simple que sous DOS (où un simple "ren *.htm *.php3" suffit, mais beaucoup plus puissant car cela permet de faire des choses totalement innaccessibles avec DOS).
La syntaxe générale est assez simple à se souvenir, car la structure de la commande est toujours la même :
on utilise soit une boucle for (pour un travail cantonné au même répertoire) soit la commande find (pour un travail récursif sur les sous-répertoires), puis on exécute la commande voulue sur chaque fichier.
Par exemple, pour renommer tous les fichiers .htm en .php3:
for i in *.htm; do mv $i `echo $i | sed "/.htm/s//.php3/"`; done
ou
find . -name "*.htm" -exec mv {} `echo {} | sed "/.htm/s//.php3/"` \;
Equivalent DOS :
ren *.htm *.php3

Explications :


  • for : la boucle for va positionner successivement la valeur de la variable $i au nom de tous les fichiers *.htm, puis pour chaque valeur de $i, exécuter la commande mv (move, pour déplacer et/ou renommer) du fichier $i (la variable de la boucle for) vers la transformation de $i. Ici, on remplace .htm par .php3 avec la commande sed.
  • find : on exécute la même commande ; find exécute pour chaque fichier la ligne de commande présente après -exec (qui doit se terminer par \;) et remplace toute occurence de {} dans cette ligne de commande le nom du fichier trouvé.


De même, pour renommer tous les fichiers commençant par "toto" en fichiers commençant par "titi" :

for i in toto*; do mv $i `echo $i | sed "/^toto/s//titi/"`; done
(ren toto*.* titi*.* en DOS)

Pour changer le "toto" présent dans le nom des fichiers en "titi", où qu'il se trouve (début, fin, ou milieu) :
for i in *toto*; do mv $i `echo $i | sed "/toto/s//titi/"`; done
(pas d'équivalent en DOS)

Pour copier tous les fichiers finissant par .htm ou .html vers le même nom auquel on ajoute .bak :
for i in *.htm*; do cp $i $i.bak; done
la même chose, mais récursivement sur tous les répertoires :
find . -name "*.htm*" -exec cp {} {}.bak \;
(pas d'équivalent en DOS)

Bref, la structure qui modifie le nom du fichier est globalement toujours la même : "commande $i `echo $i | commande_qui_transforme_$i`" (pour modifier la valeur de $i, voir les pages de man de sed, tr...), ou "commande $i append$iprepend" (pour ajouter avant et/ou après $i). Voir également ci-dessous :

Comment renommer automatiquement des fichiers de manière à remplacer les espaces par des underscores, et supprimer les accents en conservant les majuscules ?
Tapez sur une seule ligne de commande :
for i in * ; do mv "$i" `echo $i | tr "àçéèêëîïôöùüÂÇÉÈÊËÎÏÔÖÙÜ " "aceeeeiioouuACEEEEIIOOUU_"` ; done
(merci à Charles Goyard pour ses remarques)
Un bon exercice peut être de trouver comment faire la même chose mais sur les fichiers du répertoire et de ses sous-répertoires (utilisez find !)

Comment effacer tous les fichier *.tmp dans un répertoire et ses sous-répertoires ?
Nous allons utiliser find :
find . -name "*.tmp" -exec rm -f {} \;
(les accolades {} sont remplacées par le nom du fichier en