Affichage des articles dont le libellé est commande. Afficher tous les articles
Affichage des articles dont le libellé est commande. Afficher tous les articles

小山 (petite montagne)

 

Climb the small mountain.

Perform Hangetsu, slowly.

Descend.




La commande du mois : faire le point


Imaginons cette situation complètement dingue : vous avez besoin du caractère point dans une commande shell (bash), mais il vous est formellement interdit de taper le caractère point directement.


Easy peasy lemon squeezy

Simple comme bonjour me direz-vous : echo -e '\x2e' et c'est réglé.

En effet. Mais nous allons compliquer le problème. Imaginons maintenant que vous soyez sévèrement limité en taille. Enfin pas vous personnellement hein, juste la longueur de votre commande.


Bash golf

C'est un problème de code golf où il faut obtenir un résultat donné de la manière la plus compacte possible. La commande echo -e '\x2e' donnée plus haut fait 14 de long. Voici mes essais successifs pour raccourcir, aidé en partie par l'IA.

echo -e '\x2e'
echo -e \\056
printf \\x2e
printf \\56    (*)
echo $'\56'
   (**)


And the winner is

Mais mon record absolu c'est cette commande là :

ls -d

Youhoooo ! Je suis un petit peu content parce que l'ai trouvée dans ma tête avec mon cerveau perso. Même qu'après, une IA très intelligente m'a dit que j'avais fait fort. Sbraaaaaa !


Jusqu'à preuve du contraire ?

Ce qui est bien avec une commande aussi courte, 5 caractères, c'est la possibilité d'énumérer exhaustivement toutes les commandes strictement plus courtes et de tester leur sortie. Ça nécessite deux trois précautions techniques quand même, mais ça m'a l'air faisable. À suivre...



(*) Merci l'IA pour celui-ci, je ne savais pas que printf interprétait directement l'octal \56 sans zéro en préambule \056.
(**) Merci l'IA aussi, je n'avais pas pensé aux chaines ANSI-C du type $' ... '

La commande du mois : afficher tout le texte


Sous linux, cette commande affiche récursivement le contenu de tous les fichiers texte à partir du répertoire courant, en évitant soigneusement les fichiers binaires :

grep -Irh ^

Explication

L'option -I permet de sélectionner uniquement les fichiers texte. L'option -r permet de visiter récursivement tous les sous répertoires. L'option -h évite de précéder chaque ligne du nom du fichier dont elle est extraite.

Le motif ^ indique un début de ligne. Par définition ce motif est présent dans chaque ligne de n'importe quel fichier. Au final, ça dit bien : "afficher récursivement chaque ligne de chaque fichier texte".


Variante

Pour lister le nom des fichiers texte plutôt que leur contenu, utilisez l'option -l plutôt que -h.

L'option -l affiche une seule fois le nom de chaque fichier qui contient au moins une fois le motif. Mnémotechnique: Irl ça sonne comme dans "In Real Life"

grep -Irl ^ 

Application

Connaître la proportion en pourcentage de fichiers textes dans une hiérarchie de répertoires :

echo "$(bc <<< $(grep -Irl ^ | wc -l)*100/$(grep -rl ^ | wc -l))%"



Ah les grep de Bretagne !

La commande du mois : sélectionner des lignes


Il arrive de vouloir sélectionner uniquement des lignes de texte situées entre deux marqueurs.


Exemple

Par exemple dans L'Herbe rouge de Boris Vian, je veux conserver les lignes entre Carla et Wolf. Plus précisément, je veux tout ce qu'il y a entre une première ligne qui contient Carla et une prochaine ligne qui contient Wolf

Pour ça je vais utiliser la commande sed parce que, on ne le répètera jamais assez, sed c'est bien.


sed -n '/Carla/,/Wolf/p' lherberouge.txt


Explication

L'option -n permet de n'afficher a priori aucune ligne. /Carla/ est le premier séparateur. La virgule maintient une plage jusqu'à la rencontre du second séparateur /Wolf/. Tant qu'on est dans cette plage, le p provoque l'affichage de la ligne en cours.


Avec cette commande, les deux séparateurs peuvent tout à fait être identiques. Par exemple, si la zone de texte à conserver est délimitée par des ciseaux en ascii-art:

sed -n '/---- %< ----/,/---- %< ----/p' decoupezmoi.txt


Application

J'ai un grand nombre de fichiers html, je veux sélectionner seulement les headers.


sed -n '/<head>/,/<\/head>/p' *.html


Variante

Cette variante, compacte et mnémotechnique, utilise awk.


awk '/Colin/,/Chloé/' lecumedesjours.txt


Attention en revanche, ça ne donne pas le résultat attendu quand les deux séparateurs sont identiques. C'est pour ça que j'aime un peu moins. Et puis, je le rappelle :