Installé avec le paquet findutils
Voir aussi : touch
Remarques :
- Si le chemin précisé est relatif, le résultat est une liste de chemins relatifs
- Si le chemin précisé est absolu, le résultat est une liste de chemins absolus
- L’option -print est implicite, par défaut : elle ajoute un saut de ligne (\n) après chaque résultat, permettant ainsi de séparer des fichiers comportant des espaces
- L’option -print0 est à préférer à la précédente : elle ajoute un caractère nul (\0) après chaque résultat
- Il est possible d’inverser le résultat avec « ! » ou « -not » placé devant le paramètre (ex : ! -mtime +1, soit les fichiers dont le mtime n’est pas supérieur à 24h, donc équivaut à -mtime -1)
Afficher la version de la commande find
find --version
ou
apt-cache policy findutils
Effectuer une recherche par nom
find path [path...] -name "pattern"
ex :
# find dirtest/ -name "*.txt"
dirtest/file1.txt
dirtest/file2.txt
dirtest/file3.txt
Effectuer une recherche par nom sans respecter la casse
find path -iname "pattern"
Effectuer une recherche par type de fichiers
find path [path...] -type filetype
Les types de fichiers sont les suivants :
- f : Fichier régulier
- d : Répertoire
- l : Lien symbolique
- b : Fichier spécial en mode bloc (avec tampon)
- c : Fichier spécial en mode caractère (sans tampon)
- s : Socket
- p : Tube nommé (FIFO)
ex :
# find dirtest/ -type f
dirtest/file2.txt
dirtest/file1.txt
dirtest/file3.txt
dirtest/file4.png
dirtest/file5.bmp
dirtest/file6.tif
dirtest/file7.avi
dirtest/file8.mp4
dirtest/file9.mkv
# find dirtest/ -type d
dirtest/
dirtest/dir1
dirtest/dir1/ssdir11
dirtest/dir1/ssdir12
dirtest/dir2
dirtest/dir2/ssdir21
dirtest/dir2/ssdir22
Effectuer une recherche par propriétaires
Par utilisateur propriétaire
find path -user username
find path -uid userid
Par groupe propriétaire
find path -group groupname
find path -gid groupid
Effectuer une recherche par taille
find path -size [+-]value(ckMG)
La valeur indiquée est un multiple de l’octet :
- c : octets
- k : kilo-octets
- M : mega-octets
- G : Giga-octets
ex :
Fichiers/dossiers de 10Mo exactement :
# find . -size 10M
Fichiers/dossiers de plus de 10Mo :
# find . -size +10M
Fichiers/dossiers de taille comprise entre 10Mo et 30Mo :
# find . -size +10M -size -30M
Fichiers/dossiers vides :
# find . -empty
ou les fichiers de taille nulle (un répertoire vide fait 4096 octets) :
# find . -size 0
Effectuer une recherche par date de modification mtime
Par tranches de 60 secondes
find path -mmin [+-]number
ex :
Fichiers modifiés il y a moins de 1 min
# find . -mmin -1
Fichiers modifiés il y a plus de 1 min
# find . -mmin +1
Fichiers modifiés il y a plus de 3 min
# find . -mmin +3
Par tranches de 24h
find path -mtime [+-]number
ex :
Fichiers modifiés il y a moins de 24h
# find . -mtime -1
Fichiers modifiés il y a plus de 24h
# find . -mtime +1
Fichiers modifiés il y a plus de 72h
# find . -mtime +3
Plus récemment qu’un fichier servant de référence
find path -newer reffilename
ex :
Fichiers modifiés plus récemment que le fichier de référence file1.txt :
# find . -newer file1.txt
Plus récemment qu’une date spécifiée
find path -newermt "time"
ex :
Fichiers modifiés depuis 15h30 le 10/12/2016 :
# find . -newermt "2016-12-10 15:30"
Fichiers modifiés depuis 15h30 :
# find . -newermt "15:30"
Fichiers modifiés il y a moins de 30 secondes :
# find . -newermt "-30 seconds"
Effectuer une recherche par date d’accès atime
Par tranches de 60 secondes
find path -amin [+-]number
ex :
Fichiers de date d’accès inférieure à 1 min
# find . -amin -1
Fichiers de date d’accès supérieure à 1 min
# find . -amin +1
Fichiers de date d’accès supérieure à 3 min
# find . -amin +3
Par tranches de 24h
find path -atime [+-]number
ex :
Fichiers de date d’accès inférieure à 24h
# find . -atime -1
Fichiers de date d’accès supérieure à 24h
# find . -atime +1
Fichiers de date d’accès supérieure à 72h
# find . -atime +3
Plus récemment que le mtime d’un fichier servant de référence
find path -anewer reffilename
Attention, c’est bien le mtime du fichier qui sert de référence.
ex :
Fichiers accédés plus récemment que le mtime du fichier de référence file1.txt :
# find . -anewer file1.txt
Plus récemment qu’une date spécifiée
find path -newerat "time"
ex :
Fichiers accédés depuis 15h30 le 10/12/2016 :
# find . -newerat "2016-12-10 15:30"
Fichiers accédés depuis 15h30 :
# find . -newerat "15:30"
Fichiers accédés il y a moins de 30 secondes :
# find . -newerat "-30 seconds"
Effectuer une recherche par date de changement de statut ctime
Par tranches de 60 secondes
find path -cmin [+-]number
ex :
Fichiers de date de changement de statut inférieure à 1 min
# find . -cmin -1
Fichiers de date de changement de statut supérieure à 1 min
# find . -cmin +1
Fichiers de date de changement de statut supérieure à 3 min
# find . -cmin +3
Par tranches de 24h
find path -ctime [+-]number
ex :
Fichiers de date de changement de statut inférieure à 24h
# find . -ctime -1
Fichiers de date de changement de statut supérieure à 24h
# find . -ctime +1
Fichiers de date de changement de statut supérieure à 72h
# find . -ctime +3
Plus récemment que le mtime d’un fichier servant de référence
find path -cnewer reffilename
ou
find path -newercm reffilename
Attention, c’est bien le mtime du fichier qui sert de référence.
ex :
Fichiers dont le statut a changé plus récemment que le mtime du fichier de référence file1.txt :
# find . -cnewer file1.txt
# touch /tmp/MARK # find / -newercm /tmp/MARK ! -path "/proc/*" ! -path "/sys/*" ! -path "/run/*" ! -path "/dev/*" 2> /dev/null
Plus récemment qu’une date spécifiée
find path -newerct "time"
ex :
Fichiers dont le statut a changé depuis 15h30 le 10/12/2016 :
# find . -newerct "2016-12-10 15:30"
Fichiers dont le statut a changé depuis 15h30 :
# find . -newerct "15:30"
Fichiers dont le statut a changé il y a moins de 30 secondes :
# find . -newerct "-30 seconds"
Effectuer une recherche par permissions
Tests effectués avec les fichiers suivants :
drwxr-xr-x 2 ftpuser adminsys 4096 déc. 10 22:59 . drwxrwxrwx 41 adminsys adminsys 4096 déc. 10 11:39 .. -rw-rw-rw- 1 root root 0 déc. 10 11:00 file1.txt -rw-r--r-- 1 root root 0 déc. 10 12:02 file2.txt -rw-r--r-- 1 root root 0 déc. 10 12:02 file3.txt -rw-rw-rw- 1 root root 0 déc. 10 12:16 file4.png -rw-r--r-- 1 root root 0 déc. 10 12:16 file5.bmp -rw-r--r-- 1 root root 0 déc. 10 12:16 file6.tif -rw-rw-rw- 1 root root 0 déc. 10 12:17 file7.avi -rw-r--r-- 1 root root 0 déc. 10 12:17 file8.mp4 -rw-r--r-- 1 root root 0 déc. 10 12:17 file9.mkv -rwxrwxrw- 1 root root 0 déc. 10 22:36 file10.sh -rwxrwxrw- 1 root root 0 déc. 10 22:36 file11.sh -rwx------ 1 root root 0 déc. 10 22:46 file12.sh
Droits exacts
find path -perm u=(rwx),g=(rwx),x=(rwx)
ou
find path -perm (0-7)(0-7)(0-7)
ex :
# find . -perm u=rw,g=rw,o=rw # find . -perm a=rw # find . -perm 666 ./file1.txt ./file4.png ./file7.avi
Ci-dessus, on recherche strictement tout fichier dont :
- le propriétaire possède les droits de lecture et d’écriture, et uniquement ceux-là
- le groupe propriétaire possède les droits de lecture et d’écriture, et uniquement ceux-là
- les autres possèdent les droits de lecture et d’écriture, et uniquement ceux-là
# find . -perm u=x,g=x # find . -perm 110
Ci-dessus, on recherche strictement tout fichier dont :
- le propriétaire possède le droit d’exécution, et uniquement celui-là
- le groupe propriétaire possède le droit d’exécution, et uniquement celui-là
- les autres n’ont aucun droit sur le fichier
La commande ne retourne aucun résultat.
Droits minimums (mode ET)
find path -perm -u=(rwx),g=(rwx),x=(rwx)
ou
find path -perm -(0-7)(0-7)(0-7)
ex :
# find . -perm -u=rw,g=rw,o=rw # find . -perm -a=rw # find . -perm -666 ./file1.txt ./file4.png ./file7.avi ./file10.sh ./file11.sh
Ci-dessus, on recherche tout fichier dont :
- le propriétaire possède au minimum les droits de lecture et d’écriture, mais aussi éventuellement le droit d’exécution
- ET
- le groupe propriétaire possède au minimum les droits de lecture et d’écriture, mais aussi éventuellement le droit d’exécution
- ET
- les autres possèdent au minimum les droits de lecture et d’écriture, mais aussi éventuellement le droit d’exécution
# find . -perm -u=x,g=x # find . -perm -110 . ./file10.sh ./file11.sh
Ci-dessus, on recherche tout fichier dont :
- le propriétaire possède au minimum le droit d’exécution, mais aussi éventuellement les droits de lecture et d’écriture
- ET
- le groupe propriétaire possède au minimum le droit d’exécution, mais aussi éventuellement les droits de lecture et d’écriture
# find / -perm -u=s,g=s -type f # find / -perm -6000 -type -f [...] /usr/bin/at /usr/lib/xorg/Xorg.wrap
Ci-dessus, on recherche tout fichier dont :
- le propriétaire possède au minimum le SUID
- ET
- le groupe propriétaire possède au minimum le SGID
Droits minimums (mode OU)
find path -perm /u=(rwx),g=(rwx),x=(rwx)
ou
find path -perm /(0-7)(0-7)(0-7)
Dans ce mode, des recherches comme /444 ou /222 ou /111 sont beaucoup plus pertinentes, afin de se focaliser sur un bit particulier.
ex :
# find . -perm /u=rw,g=rw,o=rw # find . -perm /a=rw # find . -perm /666 . ./file1.txt ./file2.txt ./file3.txt ./file4.png ./file5.bmp ./file6.tif ./file7.avi ./file8.mp4 ./file9.mkv ./file10.sh ./file11.sh ./file12.sh
Ci-dessus, on recherche tout fichier dont :
- le propriétaire possède soit le droit de lecture soit le droit d’écriture ou les deux, mais aussi éventuellement le droit d’exécution
- OU
- le groupe propriétaire possède soit le droit de lecture soit le droit d’écriture ou les deux, mais aussi éventuellement le droit d’exécution
- OU
- les autres possèdent soit le droit de lecture soit le droit d’écriture ou les deux, mais aussi éventuellement le droit d’exécution
# find . -perm /u=x,g=x # find . -perm /110 . ./file10.sh ./file11.sh ./file12.sh
Ci-dessus, on recherche tout fichier dont :
- le propriétaire possède au minimum le droit d’exécution, mais aussi éventuellement les droits de lecture et d’écriture
- OU
- le groupe propriétaire possède au minimum le droit d’exécution, mais aussi éventuellement les droits de lecture et d’écriture
# find / -perm /u=s,g=s -type f # find / -perm /6000 -type -f [...] /bin/ntfs-3g /bin/mount /bin/ping /bin/umount /bin/su /sbin/unix_chkpwd
Ci-dessus, on recherche tout fichier dont :
- le propriétaire possède au minimum le SUID
- OU
- le groupe propriétaire possède au minimum le SGID
Rechercher les liens symboliques
find path -type l
Rechercher les liens physiques vers un même inode
find path -type f -links [+-]number
ex :
# find / -type f -links +2 -print0 2> /dev/null | xargs -0 ls -lAi | sort
1061744 -rw-r--r-- 7 root root 8721540 août 19 2015 /usr/lib/i386-linux-gnu/dri/kms_swrast_dri.so
1061744 -rw-r--r-- 7 root root 8721540 août 19 2015 /usr/lib/i386-linux-gnu/dri/nouveau_dri.so
1061744 -rw-r--r-- 7 root root 8721540 août 19 2015 /usr/lib/i386-linux-gnu/dri/r300_dri.so
1061744 -rw-r--r-- 7 root root 8721540 août 19 2015 /usr/lib/i386-linux-gnu/dri/r600_dri.so
1061744 -rw-r--r-- 7 root root 8721540 août 19 2015 /usr/lib/i386-linux-gnu/dri/radeonsi_dri.so
1061744 -rw-r--r-- 7 root root 8721540 août 19 2015 /usr/lib/i386-linux-gnu/dri/swrast_dri.so
1061744 -rw-r--r-- 7 root root 8721540 août 19 2015 /usr/lib/i386-linux-gnu/dri/vmwgfx_dri.so
1061745 -rw-r--r-- 5 root root 6021548 août 19 2015 /usr/lib/i386-linux-gnu/dri/i915_dri.so
1061745 -rw-r--r-- 5 root root 6021548 août 19 2015 /usr/lib/i386-linux-gnu/dri/i965_dri.so
1061745 -rw-r--r-- 5 root root 6021548 août 19 2015 /usr/lib/i386-linux-gnu/dri/nouveau_vieux_dri.so
1061745 -rw-r--r-- 5 root root 6021548 août 19 2015 /usr/lib/i386-linux-gnu/dri/r200_dri.so
1061745 -rw-r--r-- 5 root root 6021548 août 19 2015 /usr/lib/i386-linux-gnu/dri/radeon_dri.so
1186511 -rwxr-xr-x 3 root root 30240 mars 27 2015 /bin/bunzip2
1186511 -rwxr-xr-x 3 root root 30240 mars 27 2015 /bin/bzcat
1186511 -rwxr-xr-x 3 root root 30240 mars 27 2015 /bin/bzip2
Ci-dessus, recherche de tous les fichiers possédant plus de 2 liens physiques vers le même inode.
On remarque 7 liens physiques vers l’inode 1061744, 5 liens physiques vers l’inode 1061745 et 3 liens physiques vers l’inode 1186511.
Rechercher les liens physiques vers le même inode qu’un fichier
find path -samefile filename
ex :
# find / -samefile /bin/bzip2 2> /dev/null
/bin/bzcat
/bin/bzip2
/bin/bunzip2
Recherche par numéro d’inode
find path -inum inode
ex :
# find / -inum 1186511 2> /dev/null
/bin/bzcat
/bin/bzip2
/bin/bunzip2
Recherche avec listing détaillé du résultat en sortie
find path -ls
find path | xargs ls -dils
find path -exec ls -dils {} \;
find path -exec ls -dils {} +
find path -print0 | xargs -0 ls -dils
Eviter les problèmes liés aux fichiers avec espaces
Par défaut, chaque résultat est séparé du suivant avec un saut de ligne « \n » grâce à l’option « -print » implicite. Or, si le résultat est redirigé vers une commande, cette dernière agira sur chaque élément retourné séparé du suivant par un espace :
find path -print | xargs action
Donc si un fichier comporte des espaces dans son nom, le résultat ne sera pas celui attendu.
Par exemple, avec le fichier suivant :
# ls -lAi
total 0
796250 -rw-r--r-- 1 root root 0 déc. 11 00:53 fichier test avec des espaces.txt
# find . -print | xargs ls -dils
ls: impossible d'accéder à ./fichier: Aucun fichier ou dossier de ce type
ls: impossible d'accéder à test: Aucun fichier ou dossier de ce type
ls: impossible d'accéder à avec: Aucun fichier ou dossier de ce type
ls: impossible d'accéder à des: Aucun fichier ou dossier de ce type
ls: impossible d'accéder à espaces.txt: Aucun fichier ou dossier de ce type
On pourrait très bien signifier à xargs de considérer les éléments séparés par des saut de ligne « \n » :
# find path | xargs -d "\n" ls -dils
Toutefois, la manière optimale pour éviter ce problème consiste à séparer les résultats retournés par find avec un caractère nul et signifier à la commande de sortie xargs qu’elle distingue ces résultats grâce à celui-ci.
Le paramètre -print0 ajoute un caractère nul « \0 » à la fin de chaque élément trouvé. La commande xargs -0 sépare chaque élément à traiter grâce à ce caractère.
find path -print0 | xargs -0 action
Equivaut à :
find path -print0 | xargs -d "\0" action
# find . -print0 | xargs -0 ls -dils
796256 4 drwxr-xr-x 2 root root 4096 déc. 11 00:54 .
796250 0 -rw-r--r-- 1 root root 0 déc. 11 00:53 ./fichier test avec des espaces.txt
Exécuter une commande en sortie de la commande find
find path -print0 | xargs -0 commande
ou
find path -exec commande
ou
find path -ok commande
Le paramètre -ok demande une confirmation avant l’exécution de la commande, contrairement à -exec, donc si la commande consiste en une suppression de fichiers, une demande de confirmation aura lieu pour chaque fichier trouvé.
ex :
# find . -print0 | xargs -0 ls -dils
# find . -exec ls -dils {} \;
# find . -exec ls -dils {} +
Exécuter grep en sortie de la commande find
find path -type f -print0 | xargs -0 grep "pattern"
ex :
# find . -type f -print0 | xargs -0 grep "Curabitur"
./file1.txt:Curabitur ullamcorper ultricies nisi.
./file1.txt:Curabitur ligula sapien, tincidunt non, euismod vitae, posuere imperdiet, leo.
./file3.txt:Curabitur ullamcorper ultricies nisi.
./file3.txt:Curabitur ligula sapien, tincidunt non, euismod vitae, posuere imperdiet, leo.
find path ! -regex ".*/\..*" -print0 | xargs -0 grep "pattern"
Cette dernière commande exclura les fichiers et dossiers cachés du résultat.
Recherche avec opérateur booléen
find path [!] -parameter argument [[! -a -o] -parameter argument]
Sachant que :
- L’option -a représente l’opérateur ET logique
- L’option -o représente l’opérateur OU logique
- L’option ! représente la négation, inversant le résultat du paramètre qui suit
- Le ET logique (option -a) est implicite et n’a pas besoin d’être précisé
ex :
# find . -name "*.png" -o -name "*.bmp" -o -name "*.tif"
./file6.tif
./file4.png
./file5.bmp
# find . ! \( -name "*.png" -o -name "*.bmp" -o -name "*.tif" \) -type f
./file13.sh
./file2.txt
./file10.sh
./file11.sh
./file1.txt
./file8.mp4
./file9.mkv
./file12.sh
./file7.avi
./file3.txt
Déplacer plusieurs types de fichiers
find . -type f \( -name "*.jpg" -o -name "*.png" \) -print0 | xargs -0 mv -t destination/
Tout résultat en entrée de xargs est déplacé dans le dossier cible (-t pour target).
Copier plusieurs types de fichiers
find . -type f \( -name "*.jpg" -o -name "*.png" \) -print0 | xargs -0 cp -t destination/
Tout résultat en entrée de xargs est copié dans le dossier cible (-t pour target).
find . -type f \( -name "*.jpg" -o -name "*.png" \) -print0 | xargs -0 -I {} cp {} destination/
Chaque fichier trouvé est passé à xargs et identifié par cette dernière commande par le pattern {}
Copier plusieurs types de fichiers en les renommant
find . -type f \( -name "*.jpg" -o -name "*.png" \) -print0 | xargs -0 -I {} cp {} destination/{}.old
Chaque fichier trouvé sera renommé sur la destination avec un suffixe .old
Renommer un fichier comportant des espaces en l’identifiant par son inode
find path -inum inode -print0 | xargs -0 -I {} mv {} newfilename
ex :
# find . -inum 796271 ./fichier test avec des espaces.txt # find . -inum 796271 -print0 | xargs -0 -I {} mv {} fichier_test_avec_des_underscores.txt # find . -inum 796271 ./fichier_test_avec_des_underscores.txt
Exclure certains dossiers du résultat
find . \( -path /proc -o -path /var \) -prune -o -print
Ci-dessus exclusion des répertoires /proc et /var
Supprimer les ACL et modifier les droits en sortie
Sur les fichiers
find . -type f -print | while read obj ; do setfacl -b "${obj}"; chmod u=rw,g=rw,o-rw "${obj}"; echo "${obj}" ; done
Sur les dossiers
find . -type d -print | while read obj ; do setfacl -b "${obj}"; chmod u=rwx,g=rwxs,o-rwx "${obj}"; echo "${obj}" ; done
Find récursif affichant les lignes non commentées de plusieurs script ins d’Opsi
find . -type f -name "*.ins" -print | while read obj ; do echo "${obj}" ; sed -n '/;/!p' "${obj}"; done
Toute ligne commençant par un « ;« , signifiant une ligne commentée dans un script Opsi, n’est pas affichée.
Mais cette commande peut être généralisée par exemple en occultant les lignes commençant par un « # » :
find scriptname | while read obj ; do echo "${obj}" ; sed -n '/#/!p' "${obj}"; done
Renommer des fichiers txt comportant des espaces en les remplaçant par des underscores, dans le répertoire courant
find . -maxdepth 1 -name "*.txt" -type f | while read obj1 ; do echo "${obj1}" | sed -e 's/ /_/g' | while read obj2 ; do mv "${obj1}" "${obj2}" ; done ; done
Même chose avec plusieurs extensions :
find . -maxdepth 1 -name "*.txt" -or -name "*.odt" -or -name "*.doc" -type f | while read obj1 ; do echo "${obj1}" | sed -e 's/ /_/g' | while read obj2 ; do mv "${obj1}" "${obj2}" ; done ; done
Toujours pour plusieurs extensions mais en mode regex (variante de la commande précédente) :
find . -maxdepth 1 -regex ".*\.\(txt\|doc\|odt\)" -type f | while read obj1 ; do echo "${obj1}" | sed -e 's/ /_/g' | while read obj2 ; do mv "${obj1}" "${obj2}" ; done ; done
Même chose, quelle que soit l’extension et en remplaçant les espaces et les tirets par des underscores :
find . -maxdepth 1 -regex ".*\.*" -type f | while read obj1 ; do echo "${obj1}" | sed -e 's/ \|-/_/g' | while read obj2 ; do mv "${obj1}" "${obj2}" ; done ; done 2> /dev/null
Même chose, sauf les fichiers cachées (regex cherchant les fichiers cachés négationnée) :
find . -maxdepth 1 \( ! -regex ".*/\..*" \) -type f | while read obj1 ; do echo "${obj1}" | sed -e 's/ \|-/_/g' | while read obj2 ; do mv "${obj1}" "${obj2}" ; done ; done 2> /dev/null