News - Logiciels Libres

ls, grep, wc -l, find : optimiser les recherches !

Par , le dans Logiciels Libres - 3 Commentaires
ls, grep, wc -l, find : optimiser les recherches !
Bonjour à tous,

Aujourd'hui, parlons ls, grep, wc -l, find. Je rebondis sur une vidéo vue sur Youtube, ça apporte un super sujet sur la ligne de commande.

Le youtubeur indiquait comment compter les MP3 d'un dossiers de manière récursive de la manière suivante :

Code BASH :
ls -R | grep mp3 | wc -l


Le résultat (faux) est de 926.
Au total, j'ai 927 MP3, car j'ai un MP3 qui a l'extension MP3 (en majuscules)

Pour pallier à cela, on utilise -i de grep pour ignorer la casse :

Code BASH :
ls -R | grep -i mp3 | wc -l


Super, on tombe sur 927.

Problème, si on a des dossiers contenant MP3 (en majuscules c'est compté), car avec ls -R et grep, on n'a pas de distinction entre fichiers et dossiers.

Comme vous le savez, je travaille dans l'administration système, et plus particulièrement Linux. Et le maitre mot, quand on a de gros fichiers à traiter; c'est d'optimiser.
Voir des commandes du style :
Code BASH :
xxxx | grep blabla | wc -l 


ça m’horripile, car grep contient une option pour compter les lignes ! -c !!

Là où
Code BASH :
ls -R | grep -i mp3 | wc -l
930


avec grep -c donne
Code BASH :
ls -R | grep -ic mp3 
930


Cool, on gagne une commande !

On veut trouver ce qui ne correspond pas ? On a l'argument -v de grep qui permet d'inverser la recherche (donc tout ce qui ne contient pas MP3 :
Code BASH :
 ls -R | grep -icv mp3 
26


On peut essayer d'affiner la recherche en enlevant les dossiers avec une expression régulière dans grep avec l'option -E :
Code BASH :
ls -Rl | grep -E -ic '^-.+mp3'


C'est le moyen le plus «simple» mais pas correct, car avec des espaces dans les fichiers, la sortie de ls termine pas par mp3 mais mp3' donc on esquive cette vérification.

Le plus «normal» serait d'utiliser la commande find, en traitant uniquement les fichiers terminant par .mp3 en ignorant la casse. On compte ensuite le nombre d’occurrences avec wc -l (je n'ai pas trouvé ni connaissance d'une telle option dans find) :

find . -type f -iname "*mp3" | wc -l

Et là on tombe sur le bon nombre de fichiers : 927 !

Question performances, find l'est plus que ls + grep + wc -l :

Code BASH :
 time ls -Rl | grep mp3 | wc -l
928
 
real    0m0.008s
user    0m0.005s
sys    0m0.003s


Code BASH :
time find . -type f -iname "*mp3" | wc -l
929
 
real    0m0.003s
user    0m0.001s
sys    0m0.002s




Petit exemple en plus : Compter l;e nombre de lignes contenant kernel dans le fichier messages :

Code BASH :
cat /var/log/messages-20170709  | grep kernel | wc -l


Pas très performant... Ceci l'est plus :

Code BASH :
grep -c kernel messages-20170709


On utilise 1 commande au lieu de 3.

Au niveau du temps de traitement :
Code BASH :
time cat messages-20170709  | grep kernel | wc -l
14033
 
real    0m0.006s
user    0m0.004s
sys    0m0.002s


Code BASH :
time grep -c kernel messages-20170709
14033
 
real    0m0.003s
user    0m0.003s
sys    0m0.000s


On voit que c'est plus performant (pas de beaucoup, mais le fichier est petit, un méga, et peu de ligne comparé aux gros systèmes). Au lieu que cat liste tout, que ça passe dans grep qui filtre et liste tout ce qui correspond et wc -l compte, là grep fait tout ! Trop de la balle !

Pour finir, grep est livré (comme cat, less ou d'autres logiciels) avec sa commande z : zgrep permettant de filtrer un fichier compressé avec gzip :

Code BASH :
zgrep -c kernel messages-20170702.gz
15639


Voyez le tout en vidéo :

N'hésitez pas à sélectionner la qualité HD en 720p ou 1080p !