# find

(Voir aussi [fd](fd.md))



La commande **find** permet de retrouver des fichiers à partir de certains critères. Elle doit être utilisé avec l'option **-print**

Les <u>critères de recherche</u> sont les suivants :

- **-name** recherche sur le nom du fichier,
- **-perm** recherche sur les droits d'accès du fichier,
- **-links** recherche sur le nombre de liens du fichier,
- **-user** recherche sur le propriétaire du fichier,
- **-group** recherche sur le groupe auquel appartient le fichier,
- **-type** recherche sur le type (d=répertoire, c=caractère, f=fichier normal),
- **-size** recherche sur la taille du fichier en nombre de blocs (1 bloc=512octets),
- **-atime** recherche par date de dernier accès en lecture du fichier,
- **-mtime** recherche par date de dernière modification du fichier,
- **-ctime** recherche par date de création du fichier.

<u>Options:</u>



#### Nom:

Recherche par <u>nom</u> (**-name**) (sensible à la case):

```bash
# Le nom exact: toto

$ find /usr -name toto -print

# Le nom contient: Casa

$ find /usr -name "*Casa*"

# L'extension est .c

$ find /usr -name " *.c " -print

# commence par un a ou A, suivi de quelque chose, et se termine par un chiffre compris entre 3 et 6

$ find . -name '[aA]*[3-6]' -print
```

Recherche par <u>nom</u> (**-iname**) (non sensible à la case):

```bash
# Le nom exact: toto

$ find /usr -iname toto -print
```

Cela renvoie à la fois des fichiers et des dossiers. Pour avoir le choix fichiers ou dossiers (**-type**):

```bash
# Pour les fichiers uniquement

$ find /usr -name toto -type f

# Pour les dossiers uniquement

$ find /usr -name toto -type d
```

Ne pas afficher les fichiers ou dossiers invisibles:

```bash
$find -not -path '*/\.*'

$find . -type f | grep -v '/\.'
```



#### Taille:

Recherche suivant la <u>taille</u> (**-size**):

- c: octet
- k: kilo
- M: méga
- G: giga



```bash
# fichiers de 30ko

$ find / -size 30k -print

# fichiers dont la taille dépasse 30ko

$ find / -size +30k -print

# fichiers dont la taille est comprise entre 30 et 100ko

$ find / -size +30k -size -100k

# fichiers de moins de 30ko

$ find / -size -30k -print


# répertoire de plus de 30k

$ find / -type d -size +30k -print
```

```bash
# fichier ou répertoire vide

$ find / -size 0
$ find / -empty

find / -type d -empty
```



#### Opérateurs logiques:

Recherche en utilisant les <u>opérateurs logiques</u>:

```bash
# Recherche les fichiers n'appartenant pas à l'utilisateur olivier.

$ find . ! -user olivier -print

# Recherche les fichiers dont le nom est a.out ou les fichiers se terminant par *.c (une condition OU l'autre).

$ find . \  ( -name a.out -o -name " *.c " \  ) -print

# Recherche les fichiers dont l'extension est .pdf, .txt ou .doc

$ find . -type f ( -name "*.txt" -o -name "*.pdf" -o -name "*.doc" )

# Recherche des fichiers dont le nom est core et d'une taille supérieure à 1Mo (une condition ET l'autre).

$ find . \  (-name core -a size +2000 \  ) -print
```



#### Date:

Rechercher <u>le plus vieux</u> fichier:

```bash
$ find / -type f -printf '%T+ %p\n' | sort | head -n 1
```

Recherche suivant la <u>date de dernière modification</u> (**-mtime**):

```bash
# modifiés il y a 30 jours

$ find / -mtime 30 -print

# modifiés il y a 30 jours ou plus

$ find / -mtime +30 -print

# modifiés il y a 30 jours ou moins

$ find / -mtime 30 -print

# modifiés il y a plus de 50 jours et moins de 100

$ find / -mtime +50 –mtime -100

# modifiés dans la dernière heure

$ find / -mmin -60

# accédées dans la dernière heure

$ find / -amin -60
```

```bash
$ find . -mtime +0 # find files modified greater than 24 hours ago
$ find . -mtime 0 # find files modified between now and 1 day ago (i.e., in the past 24 hours only)
$ find . -mtime -1 # find files modified less than 1 day ago (SAME AS -mtime 0)
$ find . -mtime 1 # find files modified between 24 and 48 hours ago
$ find . -mtime +1 # find files modified more than 48 hours ago
```



#### Permissions:

Rechercher des <u>permissions</u>:

```bash
$ find /volume1/@appstore/PHP7.4/etc -perm 644
/volume1/@appstore/PHP7.4/etc/php/conf.d/memcached.ini
/volume1/@appstore/PHP7.4/etc/php/conf.d/redis.ini

$ ls -la
-rw-r--r--    1 root     root            25 Sep 14 13:39 memcached.ini
-rw-r--r--    1 root     root            21 Sep 14 13:39 redis.ini
```

<u>Inverser</u> la recherche (!):

```bash
$ find /volume1/@appstore/PHP7.4/etc ! -perm 644
/volume1/@appstore/PHP7.4/etc
/volume1/@appstore/PHP7.4/etc/php
/volume1/@appstore/PHP7.4/etc/php/conf.d
```

Rechercher les fichiers avec permission 644 et les afficher avec ls:

```bash
$ find -maxdepth 1 -type f  -perm -644 -ls
   920871    148 -rw-r--r--   1 sentier  psacln     148546 Nov 14 16:37 ./12_2008.jpg
   920718    276 -rw-r--r--   1 sentier  psacln     278540 Nov 14 16:37 ./7_2017.jpg
   920675    120 -rw-r--r--   1 sentier  psacln     120837 Nov 14 16:37 ./5_2020.jpg

$ find -maxdepth 1 -type f  -perm -644 -exec ls -la {} \;
-rw-r--r-- 1 sentier psacln 89608 Nov 14 16:37 ./11_2018.jpg
-rw-r--r-- 1 sentier psacln 258835 Nov 14 16:37 ./9_2007.jpg
-rw-r--r-- 1 sentier psacln 343441 Nov 14 16:37 ./7_2005.jpg
```

Rechercher les fichiers avec permission 777 et les modifiés en 644:

```bash
$ find / -type f -perm 0777 -print -exec chmod 644 {} \;

# idem pour les dossiers
$ find / -type d -perm 777 -print -exec chmod 755 {} \;
```

Recherche <u>combinée</u>:

```bash
# les fichiers de l'utilisateur bruno dont les permissions sont 755

$ find / -type f -user bruno -perm 755 -print
```

Rechercher les exécutables:

```bash
$ find /var/services/homes/bruno -perm /a=x
```

Rechercher les fichiers en lecture seule:

```bash
$ find /var/services/homes/bruno -perm /u=r
```



#### Regex:

Recherche avec <u>regex</u>:

```bash
# les images avec extentions jpg|gif|png|jpeg dans le dossier Users
# -E => macOS only ??

$ find -E /Users/bruno -regex ".*\.(jpg|gif|png|jpeg)"
$ find -E $HOME/Music -regex ".*\.(mp3|flac)"

# non case-sensitive
$ find -E /Users/bruno -iregex ".*\.(jpg|gif|png|jpeg)"

# Linux / GNU find (macOS)
$ find $HOME/Music -regex ".*\.\(mp3\|flac\)"
$ gfind $HOME/Music -regex ".*\.\(mp3\|flac\)"
```



#### User / group:

```bash
$ find /home -user bruno

$ find /home -group http
```



#### Commandes en option:

```bash
# Recherche les fichiers toto et les efface.

$ find . -name toto -exec rm {}\   ;

# Pour avoir une demande de confirmation avant l'exécution de rm

$ find . -name toto -ok rm {}\   ;
```



#### Utilisation avec d'autres commandes:'

```bash
# Recherche les fichiers normaux dans le répertoire courant, puis chercher le chaine toto dans ces fichiers.

$ find . -type f -print | xargs grep toto

# Recherche les fichiers toto et les efface après confimation (-p).
# idem -exec, " | xargs " ne crée qu'un seim processus.

$ find . -name toto  | xargs -p rm
```



#### Effacer tous les fichiers d'un dossier sauf un:

```bash
$ find . -type f ! -name 'fichier-a-garder.tar.gz' -delete
```



#### Présentation de la sortie:

l'option -ls correspond à un 'ls -dils'

```bash
$ find /var/services/homes/bruno -name "*php*.ini" -ls
    56408     72 -rwxrwxrwx   1 bruno    users       72040 Nov 10  2017 /var/services/homes/bruno/Drive/Drive/Apache\ -\ PHP/Backup\ Silverbook/php.ini
   364193      8 -rw-r--r--   1 root     root         8169 Nov 13 10:53 /var/services/homes/bruno/php74.ini
   364195      8 -rw-r--r--   1 root     root         8145 Nov 13 10:55 /var/services/homes/bruno/php73.ini
```



#### printf

affiche le *format* indiqué sur la sortie standard

```bash
# taille en octet - nom
$ find /var/services/homes/bruno -name "*php*.ini" -printf '%s %p\n'
72040 /var/services/homes/bruno/Drive/Drive/Apache - PHP/Backup Silverbook/php.ini
8169 /var/services/homes/bruno/php74.ini
8145 /var/services/homes/bruno/php73.ini

# date - bits - user:group - taille en octet - nom
$ find /var/services/homes/bruno -name "*php*.ini" -printf "%t %M %u:%g %s %p\n"
Fri Nov 10 09:10:42.0000000000 2017 -rwxrwxrwx bruno:users 72040  9 /var/services/homes/bruno/Drive/Drive/Apache - PHP/Backup Silverbook/php.ini
Fri Nov 13 10:53:58.5922529060 2020 -rw-r--r-- root:root 8169 10 /var/services/homes/bruno/php74.ini
Fri Nov 13 10:55:50.7925348300 2020 -rw-r--r-- root:root 8145 10 /var/services/homes/bruno/php73.ini
```

|      |                                                              |
| ---- | ------------------------------------------------------------ |
| %u   | Nom du propriétaire du fichier                               |
| %g   | Nom du groupe propriétaire du fichier                        |
| %s   | Taille du fichier en octets                                  |
| %k   | Taille du fichier en ko                                      |
| %p   | Nom du fichier                                               |
|      |                                                              |
| %t   | Date de dernière modification du fichier                     |
| %Tk  | Date de dernière modification du fichier                     |
| %m   | Bits d'autorisation d'accès au fichier (en octal)(644/755)   |
| %M   | Bits d'autorisation d'accès au fichier (symbole)(-rw-r--r--) |



#### fprintf *fichier* format

écrit le nom complet dans le *fichier*. Si *fichier* n'existe pas au démarrage de **find**, il est créé. S'il existe, il est écrasé. 



#### Redirection des messages d'erreur:

```bash
$ find /volume1/@appstore/ -name "*php*.ini"
/volume1/@appstore/PHP7.0/usr/local/etc/php70/php.ini
find: ‘/volume1/@appstore/DNSServer/named/etc/key’: Permission denied
find: ‘/volume1/@appstore/DNSServer/named/usr/lib/ocf/lib’: Permission denied
find: ‘/volume1/@appstore/DNSServer/named/usr/lib/ocf/resource.d’: Permission denied
find: ‘/volume1/@appstore/DNSServer/named/usr/lib/heartbeat/plugins’: Permission denied
/volume1/@appstore/PHP7.2/misc/php-fpm.ini
/volume1/@appstore/PHP7.2/usr/local/etc/php72/cli/php.ini
find: ‘/volume1/@appstore/Gitea/gitea/data’: Permission denied
find: ‘/volume1/@appstore/Gitea/gitea/.ssh’: Permission denied
/volume1/@appstore/PHP7.3/misc/php-fpm.ini
/volume1/@appstore/PHP7.3/usr/local/etc/php73/cli/php.ini
/volume1/@appstore/WebStation/misc/php56.ini
/volume1/@appstore/WebStation/misc/php70.ini
/volume1/@appstore/phpMyAdmin/php_conf/phpMyAdmin.ini
/volume1/@appstore/PHP7.4/misc/php-fpm.ini
/volume1/@appstore/PHP7.4/usr/local/etc/php74/cli/php.ini
```
Tous les messages d'erreurs sont redirigés avec `2>/dev/null` vers la poubelle.
```bash
$ find / -name site-packages -type d  -print 2>/dev/null


$ find /volume1/@appstore/ -name "*php*.ini" 2>/dev/null
/volume1/@appstore/PHP7.0/usr/local/etc/php70/php.ini
/volume1/@appstore/PHP7.2/misc/php-fpm.ini
/volume1/@appstore/PHP7.2/usr/local/etc/php72/cli/php.ini
/volume1/@appstore/PHP7.3/misc/php-fpm.ini
/volume1/@appstore/PHP7.3/usr/local/etc/php73/cli/php.ini
/volume1/@appstore/WebStation/misc/php56.ini
/volume1/@appstore/WebStation/misc/php70.ini
/volume1/@appstore/phpMyAdmin/php_conf/phpMyAdmin.ini
/volume1/@appstore/PHP7.4/misc/php-fpm.ini
/volume1/@appstore/PHP7.4/usr/local/etc/php74/cli/php.ini
```

C'est un peu plus propre.

Autre solution avec `grep -v "Permission denied"`, les autres messages d'erreurs restent affichés.

```bash
$ find / -name "*php*.ini" 2>&1 | grep -v "Permission denied"
/etc/php/php.ini
/volume1/@appstore/PHP7.0/usr/local/etc/php70/php.ini
/volume1/@appstore/PHP7.2/misc/php-fpm.ini
/volume1/@appstore/PHP7.2/usr/local/etc/php72/cli/php.ini
/volume1/@appstore/PHP7.3/misc/php-fpm.ini
/volume1/@appstore/PHP7.3/usr/local/etc/php73/cli/php.ini
/volume1/@appstore/WebStation/misc/php56.ini
/volume1/@appstore/WebStation/misc/php70.ini
/volume1/@appstore/phpMyAdmin/php_conf/phpMyAdmin.ini
/volume1/@appstore/PHP7.4/misc/php-fpm.ini
/volume1/@appstore/PHP7.4/usr/local/etc/php74/cli/php.ini
...
/volume1/@Entware/opt/etc/php.ini
/volume1/docker/piwigo/config/php/php-local.ini
/etc.defaults/php/php.ini
/opt/etc/php.ini
/usr/syno/etc/packages/WebStation/php70/php.ini
/usr/syno/etc/packages/WebStation/php56/php.ini
/usr/local/etc/php70/php.ini
/usr/local/etc/php73/cli/php.ini
/usr/local/etc/php74/cli/php.ini
/usr/local/etc/php72/cli/php.ini
/usr/local/etc/php72/cli/conf.d/phpMyAdmin.ini
find: ‘/proc/24000/net’: Invalid argument
```

