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 :
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 :
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 :
ça m’horripile, car grep contient une option pour compter les lignes ! -c !!
Là où
avec grep -c donne
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 :
On peut essayer d'affiner la recherche en enlevant les dossiers avec une expression régulière dans grep avec l'option -E :
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 :
Petit exemple en plus : Compter l;e nombre de lignes contenant kernel dans le fichier messages :
Pas très performant... Ceci l'est plus :
On utilise 1 commande au lieu de 3.
Au niveau du temps de traitement :
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 :
Voyez le tout en vidéo :
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 !