Commandes Linux : find

FIND

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

Laisser un commentaire