6 Perl One-Liners pour remplacer les utilitaires Linux courants
Agence web » Actualités du digital » 6 Perl One-Liners pour remplacer les utilitaires Linux courants

6 Perl One-Liners pour remplacer les utilitaires Linux courants

Alors que d'autres langages de script ont gagné en popularité, Perl reste un choix populaire en raison de ses robustes capacités de traitement de texte. Il est facile de créer des « one-liners » ou des scripts très courts, qui peuvent même remplacer les utilitaires Unix autonomes. Voici quelques outils que vous pouvez créer directement à partir de la ligne de commande.

Correspondance Regex pour remplacer grep

grep est l'un des outils Linux les plus utiles pour examiner la sortie. Il recherche du texte à l'aide d'expressions régulières, un langage précis qui vous permet de spécifier des correspondances jusqu'au niveau des caractères. Perl est connu pour ses capacités de correspondance d'expressions régulières, à tel point que de nombreux autres utilitaires et langages de programmation annoncent des expressions régulières « compatibles Perl ».

Il est facile de configurer une version Perl monoligne de grep :

        
perl -ne 'print if /PATTERN/'

Passons en revue cela. L'option -n indique à l'interpréteur Perl de supposer que cette boucle existe déjà autour du programme :

        
while (<>) {
   do_something
}

Le -n signifie que Perl prendra toute entrée provenant de l'entrée standard ou d'un nom de fichier. Les symboles supérieur et inférieur àest l'opérateur de descripteur de fichier de Perl. Perl parcourra chaque ligne du fichier et exécutera les opérations que vous avez spécifiées dans le bloc. Le motif entre les deux barres obliques sera l’expression régulière que vous essayez de faire correspondre. Voir lepage perlrun dans la documentation Perlpour plus d'informations sur les options de ligne de commande de Perl.

Le -e indiquera à Perl de ne pas rechercher un fichier source Perl, tel qu'un fichier se terminant par .pl. C'est ce qui rend les one-liners Perl possibles. En mettant cela ensemble, nous pouvons créer un petit remplacement pour le programme grep. Voyons comment cela fonctionne.

Supposons que vous vouliez rechercher des shells en cours d'exécution sur le système. Étant donné que les shells Linux se terminent généralement par sh, nous pouvons rechercher ce modèle. Pour obtenir la liste de tous les processus en cours d'exécution, vous pouvez utiliser la commande « ps aux » pour obtenir la liste des processus en cours d'exécution pour tous les utilisateurs et rediriger la sortie vers votre one-liner avec le « | » ou caractère de pipe.

Nous pourrions commencer par simplement faire correspondre le modèle « sh » :

        ps aux | perl -ne 'print if /sh/'

Cela imprimera toute ligne correspondant au motif « sh » dans la sortie du programme ps. Nous pouvons également être plus précis avec les quantificateurs de caractères. Pour faire correspondre le « s » suivi d'un h :

        ps aux | perl -ne 'print if /.sh/'
    

Nous pouvons également spécifier n’importe quel caractère contenant « sh ». Cela correspondra à des éléments comme « bash » ou « zsh ».

        
ps aux | perl -ne 'print if /.*sh/'

Assurez-vous que tout code Perl réel dans une ligne unique Perl est entre guillemets simples, afin que le shell ne les interprète pas à la place de Perl. Si vous ne le faites pas, vous recevrez un message d'erreur.

Étant donné que de nombreux noms de shell se terminent par « sh », nous pouvons rechercher tout ce qui contient « sh » à la fin d'un mot avec la classe de caractères « b » :

        
ps aux | perl -ne 'print if /.*shb/'

Non seulement cela fonctionnera avec la sortie redirigée, mais cela fonctionnera également sur les fichiers

        
perl -ne 'print if /.*sh/' example.txt

Cela imprimera n'importe quelle ligne contenant « sh » dans le fichier example.txt.

Vous pouvez également remplacer l'inverse grep, ou grep -i, en utilisant la commande « sauf si » en Perl :

        perl -ne 'print unless /sh/'
    

Impression des champs à remplacer awk

awk est un autre utilitaire Linux vénérable qui est utile pour travailler sur des données organisées en colonnes, telles que des processus ou des bases de données simples. Un one-liner Perl peut également parcourir ce code rapidement.

Supposons que nous voulions afficher le nom de l'utilisateur et le programme que l'utilisateur exécute à partir de la commande ps aux, nous écririons quelque chose comme ceci :

        
ps aux | perl -ane 'print "$F(0) $F(10)n"'

Le code Perl suppose la boucle classique « while () » autour du programme, mais il divise également l'entrée en champs. Les champs sont stockés dans un tableau appelé « @F » où un tableau est identifié par un symbole « at » (@). Pour obtenir les valeurs du tableau, vous ajoutez le nom avec un signe dollar et le numéro du champ sous forme de nombre, en commençant par 0 pour le premier élément. Perl est critiqué pour le prétendu désordre lié à l'utilisation de « sceaux » comme le signe dollar pour identifier les variables, mais c'est facile à comprendre une fois que vous connaissez cette convention.

Faites également attention à la citation. Cette expression Perl avec les variables devra être entre guillemets doubles dans l'expression entre guillemets simples pour s'assurer que l'interpréteur Perl la voit.

L'exemple ci-dessus imprimera la première colonne, $F(0), qui est le nom d'utilisateur, tandis que $F(10) récupère le nom de chemin de l'exécutable associé à ce processus. C'est ainsi que la version Linux de ps rapporte sa sortie. Si vous utilisez un système BSD, vous devrez peut-être l'ajuster. Un one-liner similaire fonctionnerait avec n'importe quel autre programme utilisant des données disposées de cette manière.

Vous pouvez utiliser le commutateur -F pour spécifier un modèle sur lequel diviser les lignes. Pour une sortie séparée par deux points, vous utiliseriez quelque chose comme :

        perl -F '/:/'
    

Rechercher et remplacer pour remplacer Sed

Vous avez peut-être exécuté une opération de recherche et de remplacement en utilisant la construction s/old/new/ soit dans Vim, soit sur la ligne de commande à l'aide du programme sed. Étant donné que la fonction de recherche et de remplacement d'expressions régulières de Perl semble, euh, « inspirée » de cet utilitaire Unix classique, elle est facile à traduire en une seule ligne Perl :

        perl -pe "s/old/new/"
    

Cela fonctionnera à la fois avec une entrée canalisée et sur la ligne de commande seule. J'espère que si Randal Schwartz lit ceci, il ne me décernera pas le prix « Utilisation inutile du chat ». Par exemple, pour remplacer « chien » par « chat »

        perl -pe "s/dog/cat"

Vous pouvez l'essayer sur quelque chose comme « J'aime caresser mon chien ».

Le mot « chien » sera remplacé par « chat ».

Si vous essayez ceci sur une ligne telle que « L'haleine de mon chien sent la nourriture pour chien », avec plusieurs instances du motif que vous souhaitez remplacer dans la ligne, vous remarquerez peut-être que seule la première occurrence est remplacée :

My cat's breath smells like dog food.

Si l'haleine de votre chat sent réellement la nourriture pour chien, cela serait suffisant. Vous pouvez également remplacer chaque instance en ajoutant l'opérateur « s/old/new » d'origine par « g » pour « global.

Assurons-nous que l'haleine de votre chat sent la nourriture pour chat :

        
perl -pe "s/dog/cat/g"

Désormais, chaque instance du motif sera remplacée lorsqu'elle apparaîtra dans la ligne.

Tri pour remplacer le tri

Vous pouvez utiliser le tri pour trier les entrées standard par ordre alphabétique. C'est aussi facile à faire avec une seule ligne

        perl -e "print sort <>"

Cela indiquera à Perl de trier l'entrée standard, qui inclut à nouveau tout fichier spécifié depuis la ligne de commande, ou transmis depuis une autre commande, et de trier la sortie par ordre alphabétique, ou plutôt selon le paramètre « locale » de votre système. Dans mon cas, c'est C.UTF-8. Si votre système est configuré pour utiliser une langue différente, les lignes peuvent être triées différemment. Sur mon système, les lignes avec des majuscules semblent être triées en premier.

Supprimer les doublons pour remplacer uniq

uniq est utilisé dans les listes avec le tri pour supprimer les entrées en double. Vous pouvez reproduire la fonctionnalité avec ce one-liner :

        
perl -ne 'print if $_ ne $prev; $prev = $_'

Cela comparera la ligne actuelle à la précédente et l'imprimera si elles sont inégales. La variable « $_ » est un raccourci pour la ligne de saisie actuelle. Bien que ce one-liner démontre certains concepts Perl, je m'en tiendrai probablement à uniq dans la pratique, car il ne comporte que quatre caractères.

Vous pouvez même combiner des one-liners avec des tuyaux au niveau de la coque. Voici un exemple pour imprimer des éléments uniques générés par une ligne unique qui sélectionne les champs de la sortie mentionnée précédemment :

        ps aux | perl -ane 'print "$F(0)n"' | perl -ne 'print if $_ ne $prev; $prev = $_'

Remplacement de tr pour le remplacement de caractères

Alors que vous avez vu l'opérateur de recherche et de remplacement précédent travailler sur des expressions régulières, la commande tr sous Linux fonctionne sur des caractères individuels et des classes de caractères. Supposons que vous vouliez mettre un fichier en majuscule, pour donner l'impression que vous criiez constamment, vous utiliseriez cette seule ligne pour remplacer tr :

        T
perl -pe 'tr/a-z/A-Z/'

Cela remplacera chaque caractère minuscule de a à z par son homologue majuscule.


Ces one-liners devraient vous donner un avant-goût de la puissance de traitement de texte de Perl et montrer pourquoi le langage a encore un peu de vie. Vous pouvez faire beaucoup de choses avec un peu de code en Perl.

★★★★★