Guide du débutant sur Shell Scripting 2: For Loops

Table des matières:

Guide du débutant sur Shell Scripting 2: For Loops
Guide du débutant sur Shell Scripting 2: For Loops

Vidéo: Guide du débutant sur Shell Scripting 2: For Loops

Vidéo: Guide du débutant sur Shell Scripting 2: For Loops
Vidéo: La HISTORIA DETRÁS del PRIMER Crash Bandicoot 🦊 - YouTube 2024, Novembre
Anonim
Si vous souhaitez développer votre credo geek, rejoignez-nous pour le deuxième volet de notre série de scripts shell. Nous avons quelques corrections à apporter, quelques améliorations au script de la semaine dernière et un guide sur la mise en boucle pour les non-initiés.
Si vous souhaitez développer votre credo geek, rejoignez-nous pour le deuxième volet de notre série de scripts shell. Nous avons quelques corrections à apporter, quelques améliorations au script de la semaine dernière et un guide sur la mise en boucle pour les non-initiés.

Le script datecp revisité

Dans la première partie de notre guide de script shell, nous avons créé un script qui copiait un fichier dans un répertoire de sauvegarde après avoir ajouté la date à la fin du nom de fichier.

Samuel Dionne-Riel a souligné dans ses commentaires qu’il y avait une meilleure façon de gérer nos références variables.

Arguments are space-separated in the bash shell, it will tokenize when there is a space in the resulted expanded command. In your script,

cp $1 $2.$date_formatted

fonctionnera comme prévu tant que les variables développées n’ont pas d’espace. Si vous appelez votre script de cette façon:

datecp 'my old name' 'my new name'

l'expansion entraînera cette commande:

cp my new name my old name.the_date

qui a en fait 6 arguments.

Pour résoudre correctement ce problème, la dernière ligne du script devrait être:

cp '$1' '$2.$date_formatted'

Comme vous pouvez le voir, changer la ligne de notre script de:

cp -iv $1 $2.$date_formatted

à:

cp -iv “$1” “$2”.$date_formatted

résoudra ce problème lors de l'utilisation du script sur des fichiers comportant des espaces dans le nom. Samuel souligne également que, lors de la copie et du collage de code provenant de ce site (ou d'Internet en général), veillez à substituer les tirets et les guillemets appropriés à ceux «mieux typographiquement» qui les remplacent souvent. Nous ferons également plus pour nous assurer que notre code est plus convivial en copier / coller.;-)

Un autre intervenant, Myles Braithwaite, a décidé d’élargir notre script afin que la date apparaisse avant l’extension du fichier. Donc au lieu de

tastyfile.mp3.07_14_11-12.34.56

nous aurions ceci:

tastyfile.07_14_11-12.34.56.mp3

ce qui finit par être un peu plus pratique pour la plupart des utilisateurs. Son code est disponible sur sa page GitHub. Voyons ce qu’il utilise pour séparer le nom de fichier.

date_formatted=$(date +%Y-%m-%d_%H.%M%S) file_extension=$(echo “$1″|awk -F. ‘{print $NF}’) file_name=$(basename $1.$file_extension)

cp -iv $1 $file_name-$date_formatted.$file_extension

J’ai un peu modifié la mise en forme, mais vous pouvez voir que Myles déclare sa fonction de date dans la première ligne. Dans la deuxième ligne, il utilise toutefois la commande «echo» avec le premier argument du script pour extraire le nom du fichier. Il utilise la commande pipe pour prendre cette sortie et l'utiliser comme entrée pour la partie suivante. Après le tuyau, Myles appelle la commande «awk», un programme puissant d’analyse de motifs. En utilisant le drapeau -F, il dit à la commande que c'est le caractère suivant (après un espace) qui définira le «séparateur de champs». Dans ce cas, c’est un point.

Maintenant, awk voit un fichier nommé «tastyfile.mp3» composé de deux champs: «tastyfile» et «mp3». Enfin, il utilise

‘{print $NF}’

pour afficher le dernier champ. Si votre fichier contient plusieurs points (ce qui oblige awk à voir plusieurs champs), il n’affiche que le dernier, l’extension de fichier.

À la ligne 3, il crée une nouvelle variable pour le nom du fichier et utilise la commande «basename» pour référencer tout ce qui se trouve dans $ 1. sauf l'extension de fichier. Ceci est fait en utilisant basename et en lui donnant l'argument $ 1, puis en ajoutant un espace et l'extension du fichier. L’extension de fichier est automatiquement ajoutée à cause de la variable qui fait référence à la ligne 2. Cela prendrait ceci:

tastyfile.mp3

et le transformer en

tastyfile

Puis, à la dernière ligne, Myles met en place la commande qui va tout afficher dans l’ordre. Notez qu'il n'y a aucune référence à $ 2, un deuxième argument pour le script. Ce script particulier copiera ledit fichier dans votre répertoire actuel à la place. Bravo Samuel et Myles!

Scripts en cours d'exécution et $ PATH

Nous mentionnons également dans notre article de base que les scripts ne sont pas autorisés à être référencés en tant que commandes par défaut. En d’autres termes, vous devez indiquer le chemin du script pour l’exécuter:

./script

~/bin/script

Mais, en plaçant vos scripts dans ~ / bin /, vous pouvez simplement taper leurs noms de partout pour les faire fonctionner.

Les commentateurs ont passé un certain temps à débattre de sa pertinence, car aucune distribution Linux moderne ne crée ce répertoire par défaut. De plus, personne ne l’ajoute par défaut à la variable $ PATH, ce qui est nécessaire pour que les scripts puissent être exécutés comme des commandes. J'étais un peu perplexe car après avoir vérifié ma variable $ PATH, les commentateurs avaient raison, mais appeler des scripts fonctionnait toujours pour moi. J'ai découvert pourquoi: de nombreuses distributions Linux modernes créent un fichier spécial dans le répertoire personnel de l'utilisateur -.profile.

Ce fichier est lu par bash (sauf si.bash profile est présent dans le répertoire personnel de l’utilisateur). En bas, une section ajoute le dossier ~ / bin / à la variable $ PATH, le cas échéant. Donc, ce mystère est éclairci. Pour le reste de la série, je continuerai à placer des scripts dans le répertoire ~ / bin / car ils sont des scripts utilisateur et doivent pouvoir être exécutés par les utilisateurs. Et, il semble que nous n’ayons pas vraiment besoin de jouer avec la variable $ PATH à la main pour que tout fonctionne.
Ce fichier est lu par bash (sauf si.bash profile est présent dans le répertoire personnel de l’utilisateur). En bas, une section ajoute le dossier ~ / bin / à la variable $ PATH, le cas échéant. Donc, ce mystère est éclairci. Pour le reste de la série, je continuerai à placer des scripts dans le répertoire ~ / bin / car ils sont des scripts utilisateur et doivent pouvoir être exécutés par les utilisateurs. Et, il semble que nous n’ayons pas vraiment besoin de jouer avec la variable $ PATH à la main pour que tout fonctionne.

Répéter les commandes avec des boucles

Passons à l’un des outils les plus utiles de l’arsenal geek pour traiter des tâches répétitives: les boucles. Aujourd’hui, nous discuterons des boucles “for”.

La structure de base d’une boucle for est la suivante:

for VARIABLE in LIST; do command1 command2 … commandn done

VARIABLE peut être n’importe quelle variable, bien que le plus souvent, le «i» minuscule soit utilisé par convention. LISTE est une liste d'éléments; vous pouvez spécifier plusieurs éléments (en les séparant par un espace), pointer vers un fichier texte externe ou utiliser un astérisque (*) pour désigner tout fichier du répertoire en cours. Les commandes répertoriées sont mises en retrait par convention, il est donc plus facile de voir l’imbrication - mettre des boucles en boucle (afin que vous puissiez boucler pendant que vous bouclez).

Parce que les listes utilisent des espaces comme délimiteurs - c’est-à-dire qu’un espace signifie un déplacement vers l’élément suivant de la liste - les fichiers dont le nom contient des espaces ne sont pas très amicaux. Pour l’instant, travaillons avec des fichiers sans espaces. Commençons par un simple script pour afficher les noms des fichiers du répertoire en cours. Créez un nouveau script dans votre dossier ~ / bin / intitulé «Loopscript». Si vous ne vous rappelez pas comment faire cela (notamment en le marquant comme exécutable et en ajoutant le hash bang hack), reportez-vous à notre article Notions de base sur les scripts bash.

Dans celui-ci, entrez le code suivant:

for i in item1 item2 item3 item4 item5 item6; do echo “$i” done

Image
Image

Lorsque vous exécutez le script, vous devez simplement obtenir ces éléments de liste en sortie.

Assez simple, non? Voyons ce qui se passe si nous changeons un peu les choses. Changez votre script pour qu'il dise ceci:
Assez simple, non? Voyons ce qui se passe si nous changeons un peu les choses. Changez votre script pour qu'il dise ceci:

for i in *; do echo “$i” done

Lorsque vous exécutez ce script dans un dossier, vous devez obtenir une liste des fichiers qu’il contient en sortie.
Lorsque vous exécutez ce script dans un dossier, vous devez obtenir une liste des fichiers qu’il contient en sortie.
Maintenant, changeons la commande echo en quelque chose de plus utile - disons, la commande zip. Nous allons notamment ajouter des fichiers dans une archive. Et, obtenons quelques arguments dans le mélange!
Maintenant, changeons la commande echo en quelque chose de plus utile - disons, la commande zip. Nous allons notamment ajouter des fichiers dans une archive. Et, obtenons quelques arguments dans le mélange!

for i in $@; do zip archive “$i” done

Il y a du nouveau! “$ @” Est un raccourci pour “1 $ 2 $ 3  n . En d’autres termes, c’est la liste complète de tous les arguments que vous avez spécifiés. Maintenant, regardez ce qui se passe lorsque je lance le script avec plusieurs fichiers d'entrée.
Il y a du nouveau! “$ @” Est un raccourci pour “1 $ 2 $ 3 n . En d’autres termes, c’est la liste complète de tous les arguments que vous avez spécifiés. Maintenant, regardez ce qui se passe lorsque je lance le script avec plusieurs fichiers d'entrée.
Vous pouvez voir quels fichiers sont dans mon dossier. J'ai exécuté la commande avec six arguments et chaque fichier a été ajouté à une archive compressée nommée «archive.zip». Facile, non?
Vous pouvez voir quels fichiers sont dans mon dossier. J'ai exécuté la commande avec six arguments et chaque fichier a été ajouté à une archive compressée nommée «archive.zip». Facile, non?

Les boucles sont vraiment magnifiques. Vous pouvez maintenant exécuter des fonctions de traitement par lots sur des listes de fichiers. Par exemple, vous pouvez copier tous les arguments de votre script dans une archive compressée, déplacer les originaux dans un autre dossier et copier automatiquement ce fichier zip sur un ordinateur distant. Si vous configurez des fichiers de clés avec SSH, vous n’aurez même pas besoin de saisir votre mot de passe et vous pouvez même demander au script de supprimer le fichier zip après l’avoir chargé!

L'utilisation de boucles for facilite la réalisation de nombreuses actions pour tous les fichiers d'un répertoire. Vous pouvez empiler une grande variété de commandes et utiliser des arguments très facilement pour créer une liste à la volée. Il ne s'agit que de la partie visible de l'iceberg.

Scripteurs Bash, avez-vous des suggestions? Avez-vous créé un script utile utilisant des boucles? Voulez-vous partager vos réflexions sur la série? Laissez des commentaires et aidez d’autres novices en script!

Conseillé: