il est souvent utile de rechercher des fichiers pour par exemple les renommer (voir mon article sur le renommage des photos). La commande en ligne sous linux pour cela est find :
De façon basique,
La recherche de fichier
va être réaliser par :
find -iname partie_du_nom_du_fichier.ext
par exemple, après vous être positionné dans le répertoire image, vous rechercher les photos du mois de juillet 2014 (encore faut-il les avoir renommer comme cela!): find -iname 20407*.JPG
nota: il peut-être nécessaire de le faire en mode super-utilisateur, ajouter sudo sous ubuntu.
Pour aller plus loin, par exemple
Trouver une série de fichiers image entre tel et tel numéro,
l'utilisation des expressions régulières (REGEX) peut une fois encore être d'une efficacité incomparable :
find . -regextype posix-extended -regex '^./2014072[8-9]{1}.*'
me retourne ainsi mes fichiers daté du 28 ou 29 juillet qui se trouve dans le répertoire courant
-regextype posix-extended
permet d'utiliser toute la puissance des REGEX dont les expressions [0-9]{1,3}
-regex
précède l'expression régulière, le modèle (ou pattern en anglais)
À savoir :
- le modèle doit décrire tout le chemin et nom de fichier, pas uniquement une partie !
- de ce fait il faut commencer le pattern par
/.
pour le chemin du répertoire courant ou.*
si ça peut être ./sous-répertoire/fichier
Pour aller plus loin, l'option -exec :
find -iname Thumbs.db -exec rm {} \;
ou -delete
find -iname Thumbs.db -delete
Pour lister et agir sur des fichiers plus vieux de n jours :
find . -type f -iname "*.jpg" -mtime +365 -delete
et l'option -newermt
: https://askubuntu.com/a/1154062/385361
pour supprimer les fichiers Thumbs après la migration d'un partage sous Windows vers un serveur de fichiers Samba
Copier/déplacer plusieurs type de fichiers présents dans différents sous-répertoires
par exemple les fichiers d'un projet de programme :
find . -regex '.+\.\(cpp\|h\)$' -exec cp -v {} repertoire/destination/ \;
le . est pour le répertoire courant
l'expression régulière '.+\.\(cpp\|h\)$'
signifie : .+
n'importe quel nom de fichier (non vide avec +, on peut aussi mettre *) suivi par un point \.
suivi par l'extension cpp ou h pour finir ($)
-exec permet d'exécuter sur la sortie du find notre copie (cp, ou mv si déplacer) -v (verbose), {} récupère la sortie du find, vers le repetoire de destination et enfin un ; (échappé avec \) pour finir la commande.
Renommer des fichiers dans différents sous-répertoires
Pour reprendre la phrase dans doc.ubuntu-fr.org/recherche_ligne_commande#find, "find est un besogneux qui arpente vos dossiers infatigablement". C'est donc une des meilleurs solution pour trouver des fichiers. Ni mv ni rename ne savent faire. En revanche, rename, avec les regex par défaut, est très efficace sur le renomage. Il suffit donc de combiner les deux:
Voici un exemple pour renommer l'extension de fichiers header de .h à .hpp
find -iname *.h -type f -exec rename 's/(.*\.)h/$1hpp/' {} \;
et pour basculer les majuscules en minuscules des fichiers .cpp et hpp :
find -iname *.?pp -type f -exec rename 'y/A-Z/a-z/' {} \;
Remplacer les espaces des fichiers par des tirets :
find -name "* *" | rename 's/ /-/g'
voir aussi ma réponse pour renommage de nom de fichiers sur askubuntu
voir aussi : recherche en ligne de commande sur doc.ubuntu-fr.org
Modifier les permissions sur des fichiers
en évitant de modifier celle des répertoires… notamment le répetoire ..
On commence par regarder les permissions et s'assurer qu'on travaille sur les fichiers qui nous intéresse avec :
find . -maxdepth 3 -type f -iname "*.php" -exec ls -la {} \;
l'option maxdepth permet de limiter la recherche dans l'arborescence (notamment le répertoire vendor dan mon cas)
l'option type permet de ne traiter que les fichiers… f pour file, d pour directory
l'option iname de définir quelle nom de fichiers on cherche. Il est a noter que si on ne met pas les " " autour de .*, il ne trouve que dans le répertoire courant ou désigné juste après find.
Si c'est bien les fichiers qu'on souhaite modifier, on peut réaliser notre chmod :
find . -maxdepth 3 -type f -iname "*.php" -exec sudo chmod 664 {} \;
Le sudo n'est utile que si on n'est pas propriétaire (owner) des fichiers… comme dans le cas de fichiers www-data
Il est évidemment possible de faire de même pour des répertoires, et dans ce cas, faire bien attention, de ne pas prendre en compte le répertoire ../ qui impacterait les répertoires parents, et peut donc avoir des conséquences désagréables, notamment avec git qui prend en compte un changement de permissions !
Supprimer les fichiers qui ne sont pas des images dans un répertoire
find . -type f ! -iname "*.jpg" ! -iname "*.jpeg" ! -iname "*.png" ! -iname "*.svg" ! -iname "*.webp" --exec rm {} \;