Grimoire-
Command
.es

GNU+Linux command memo

Memo_6 : chercher du texte, des fichiers

D’après l’édition 11 des travaux d’Alain Leaper, 2018-04-10
Licence GPL

1. grep : recherche d’une chaîne / filtrage de la sortie d’une commande

$ grep 'chaîne' $fichier_1 $fichier_2

Recherche d’une chaîne supposée présente dans un ou plusieurs fichiers (textes en général). Les délimiteurs de chaînes (" " ou ' ') ne sont pas toujours indispensables, c’est le cas s’il n’y a pas d’espace dans la chaîne. Leur usage est cependant recommandé dans tous le cas pour éviter les erreurs, car une apostrophe arrive vite par exemple…

Par défaut, le canal d’entrée standard est le clavier et le canal de sortie standard est l’écran.

$ grep abcd (1)
hhhhabcdtttt (2)
hhhhabcdtttt (3)
$ grep ab cd ef (4)
grep: cd: Aucun fichier ou répertoire de ce type
grep: ef: Aucun fichier ou répertoire de ce type
$ grep 'ab cd ef' (1)
xxxab cd efkkkkk (2)
xxxab cd efkkkkk (3)
1 Entrée, grep demande alors qu’on saisisse des caractères
2 Entrée, grep ré-affiche les lignes contenant le motif abcd
3 Ctrl+D pour sortir
4 Entrée

Le caractère - peut être utilisé pour impliquer le canal d’entrée standard, en plus des fichiers figurant sur la ligne de commande. En l’absence de fichier - peut ou non figurer.

$ cat test
aaaaaaaaaaaaaaa
bbbb bbbbbbb
bonbons caramels
ccccc   ccccccc
$ grep 'bonbon' - test (1)
jjjjj
jjjjbonbonllll         (2)
(entrée standard):jjjjbonbonllll
test:bonbons caramels
1 Entrée
2 Entrée puis Ctrl+D
le caractère - doit être placé avant tout fichier d’entrée (ici avant test).

La redirection du canal de sortie standard vers un fichier est possible.

$ grep [] > fichierSortie

Le caractère * est utilisable pour forcer la recherche dans plusieurs fichiers.

$ grep 'printf' ./*.c (1)
1 recherche la chaîne printf dans tous les fichiers terminés par .c

Affiche le nom du (ou des) fichier(s) suivi(s) de (ou des) ligne(s) concernées.

  • L’option -r (récursion) permet d’analyser les sous-répertoires.

$ grep -r 'chaîne' ~/monRepertoire (1)
1 recherche dans le répertoire monRepertoire et ses sous-répertoires
  • L’option -n permet d’afficher les numéros des lignes impliquées.

  • L’option -l supprime l’affichage des lignes concernées, en elles-mêmes et inhibe -n.

  • L’option -i permet d’ignorer les différences majuscule/minuscule, ainsi « ChaîNE » est, pour la recherche, équivalent à « chaîne ».

  • L’option -v permet de supprimer les lignes qui contiennent la chaîne qui suit cette option :

$ grep -v 'abcd' (1)
1 affiche toutes le lignes, sauf celles qui contiennent la chaîne abcd

Les options sont cumulables, dans n’importe quel ordre (mais -l inhibe -n)

$ grep -irn 'CaRamel' ./
./ss_rep_1/ss_rep_2/fic_2:2:jjjcarameloooo
./ss_rep_1/fic_1:3:ccccarameljjj
./test:3:bonbons caramels
  • L’option -F permet de traiter les métacaractères comme des caractères normaux. Par exemple la séquence \? sera reconnue en tant que telle.

  • L’option -E permet d’utiliser les expressions régulières (regex) étendues, voir Memo_7. Par défaut (sans -E) grep utilise les expressions régulières simples.

$ grep -irnE 'Ramels$' . (1)
./test:3:bonbons caramels
1 $ : indique une correspondance avec une fin de ligne

1.1. grep derrière un tube |

Utilisation en tant que filtre de la commande précédent le tube.

$ uneCommande | grep -options 'chaîne' (1)
1 Éventuellement avec une redirection de la sortie
$ ls / | grep 'bin'
bin
sbin

1.2. Fichiers compressés

Pour les fichiers compressés, il existe une forme spéciale. Celle-ci supporte les mêmes options.

1.2.1. Fichiers compressés avec gzip

$ zgrep 'un motif' fichier.gz

1.2.2. Fichiers compressés avec bzip2

$ bzgrep -n 'un motif' fichier.bz2

1.2.3. Fichiers compressés avec xz

$ xzgrep -n 'un motif' fichier.xz

2. find recherche de fichiers dans l’arborescence des répertoires

$ find répertoireDépart -options expression (1)
1 print n’est pas nécessaire avec GNU+Linux

2.1. Quelques options

  • -name : la recherche porte sur le nom: expression est alors une chaîne (nom de fichier) joker * autorisé dans le nom

  • -iname : idem mais sans tenir compte des majuscules / minuscules

  • -regex : expression est une expression régulière, voir Memo_7

  • -iregex : idem mais sans tenir compte des majuscules / minuscules

Pour éviter les "Permission non accordée" en rafale, il est souvent judicieux de rediriger la sortie standard d’erreur dans le "trou noir"

$ find / -name 'ifconfig' 2> /dev/null
/sbin/ifconfig (1)
1 Sans avoir une flopée de "Permission non accordée".

2.2. Sélection par la date de création

find répertoireDépart -newer fichierRef (1)
find répertoireDépart -mmin N
find répertoireDépart -mtime N
1 recherche le(s) fichier(s) plus "nouveau(x)" que fichierRef
  • sans signe N : exprime une concordance exacte

  • avec signe - : de 0 à la valeur N

  • avec signe + : supérieur à la valeur de N

  • -mmin : il s’agit de minutes. Exemple: recherche dans le répertoire courant, les fichiers créés depuis moins de 10 minutes :

$ find . -mmin -10
  • -mtime : il s’agit de période(s) de 24 heures

$ find . -mtime -1

Renvoie les fichiers créés depuis moins de 24 heures (idem find . -time 0).

$ find . -mtime +1

Renvoie les fichiers créés depuis plus de 24 heures.

$ find . -mtime +2

Renvoie les fichiers créés depuis plus de 48 heures.

2.3. Sélection par la date du dernier accès (dernière modification)

  • -amin s’utilise comme -mmin

  • -atime s’utilise comme -mtime

Exemple :

$ find . -mmin -2

Renvoie les fichiers modifiés depuis moins de 2 minutes

2.4. Sélection par les droits

$ find répertoireDépart -perm droits

Les droits peuvent s’exprimer:

2.4.1. sous forme octale

$ find ~ -perm 777

Renvoie, à partir du répertoire personnel, les fichiers qui ont tous les droits activés.

2.4.2. sous forme littérale: séparer les expression par des virgules ,

$ find ~ -perm /g+w,o+r -name '.g*' (1)
1 ne pas oublier les ' ' si *

Renvoie, à partir du répertoire personnel, les fichiers .g* qui ont droits en écriture pour le groupe g et lecture pour les autres o.

Il sempble que ce soit un « ou » (inclusif).

2.5. Sélection par la taille

$ find répertoireDépart -size NindiTaille
  • N: idem ci-dessus

  • N et indiTaille (indicateur de taille) doivent être "collés"

  • indiTaille peut avoir les unités suivantes :

    • b blocs de 512 octets (valeur par défaut)

    • c en octets (character)

    • w 2 octets (word)

    • k kilo-octets (unités de 1 024 octets)

    • M méga-octets (unités de 1 048 576 octets)

    • G giga-octets (unités de 1 073 741 824 octets)

Exemple:

$ find ~ -size +100M

2.6. Sélection suivie d’une exécution

$ find . -mtime +1 -exec chmod u+x {} \;

À partir du répertoire courant (et pour tous ses sous-répertoires) sélectionne les fichiers créés depuis plus de 24 heures. Exécute pour les fichiers sélectionnés (correspond à {}) la modification des droits d’exécution pour l’utilisateur (user). Le ; doit être « échappé ».

3. locate : recherche les fichiers dont le nom contient la chaîne donnée en argument

$ locate 'lspnp'
/sbin/lspnp
/usr/share/man/man8/lspnp.8.gz

La base de recherche doit exister et être éventuellement mise à jour via la commande updatedb exécutée avec les droits administrateur.

$ sudo updatedb

4. whereis : localise un fichier exécutable dont le nom est connu

$ whereis ifconfig
ifconfig: /sbin/ifconfig /usr/share/man/man8/ifconfig.8.gz

La recherche s’effectue dans les répertoires normalisés (/bin/, /sbin …) de Linux pour les fichiers exécutables ainsi que dans les répertoires renseignés dans la variable $PATH (et respectivement $MANPATH pour les pages de manuel).

5. rg et ag : alternatives modernes et rapides

Toutes les formes de grep peuvent être remplacées par des formes généralement plus simples et plus rapides des commande rg et ag, respectivement disponibles dans les paquets Debian ripgrep et silversearcher-ag.

Comme étudié ici à travers plusieurs exemples, rg est généralement 2x plus rapide qu' ag, et jusqu’à 8x plus rapide que grep.