Il est assez facile de lire le contenu d'une ligne de fichier texte Linux en ligne dans un shell script aussi longtemps que vous traitez avec quelques précautions subtiles. Voici comment le faire de façon sécuritaire.
Fichiers texte, et idiomes
Chaque langage de programmation est un ensemble d'idiomes. Ce sont la norme, sans fioritures moyens pour accomplir un ensemble de tâches communes. Ils sont la façon élémentaire ou par défaut à utiliser l'une des caractéristiques de la langue du programmeur travaille avec. Ils font partie de la boîte à outils des plans mental d'un programmeur.
Des actions comme la lecture des données à partir de fichiers, travailler avec des boucles et échangeant les valeurs de deux variables sont de bons exemples. Le programmeur saura au moins un moyen de parvenir à leurs fins de manière générique ou à la vanille. Peut-être cela suffira pour l'exigence à portée de main. Ou peut-être qu'ils embellissent le code pour le rendre plus efficace ou applicable à la solution spécifique qu'ils développent. Mais ayant l'idiome bloc de construction à portée de main est un excellent point de départ.
Connaître et comprendre les idiomes dans une langue, il est plus facile de choisir un nouveau langage de programmation, aussi. Savoir comment les choses sont construites dans une langue et à la recherche de l'équivalent ou la chose la plus proche dans une autre langue est une bonne façon d'apprécier les similitudes et les différences entre les langages de programmation que vous connaissez déjà et celui que vous apprenez.
La lecture d'un fichier Lines: Le One-Liner
Dans Bash, vous pouvez utiliser un
tandis que
boucle sur la ligne de commande pour lire chaque ligne de texte à partir d'un fichier et faire quelque chose avec elle. Notre fichier texte est appelé « data.txt. » Il contient une liste des mois de l'année.
Janvier février Mars . . octobre novembre Décembre
Notre simple-liner est:
tandis que la ligne de lecture; faire écho $ ligne; done & lt; data.txt
Les
tandis que
boucle lit une ligne à partir du fichier, et le flux d'exécution du programme passe peu au corps de la boucle. Les
écho
commande écrit la ligne de texte dans la fenêtre du terminal. La tentative de lecture échoue quand il n'y a plus de lignes à lire, et la boucle est fait.
Une astuce est la capacité pour rediriger un fichier dans une boucle . Dans d'autres langages de programmation, vous aurez besoin d'ouvrir le fichier, lire, et le fermer à nouveau lorsque vous aviez terminé. Avec Bash, vous pouvez simplement utiliser la redirection de fichiers et de laisser la poignée de shell tous ce genre de choses de bas niveau pour vous.
Bien sûr, ce one-liner est pas très utile. Linux fournit déjà
chat
commande, qui fait exactement cela pour nous. Nous avons créé un moyen de longue haleine pour remplacer une commande de trois lettres. Mais il ne démontre visiblement les principes de la lecture d'un fichier.
Cela fonctionne assez bien, jusqu'à un certain point. Supposons que nous ayons un autre fichier texte qui contient les noms des mois. Dans ce fichier, la séquence d'échappement pour un caractère de nouvelle ligne a été annexée à chaque ligne. Nous l'appellerons « data2.txt. »
Janvier \ n Février 'n Mars 'n . . Octobre 'n Novembre 'n Décembre \ n
Utilisons notre seule ligne sur notre nouveau fichier.
tandis que la ligne de lecture; faire écho $ ligne; done & lt; data2.txt
Le caractère d'échappement backslash »
\
» A été mis au rebut. Le résultat est qu'un « n » a été annexée à chaque ligne. Bash interprète la barre oblique inverse comme le début d'une
séquence d'échappement
. , Nous ne voulons pas souvent Bash d'interpréter ce qu'il est en train de lire. Il peut être plus commode de lire une ligne dans ses séquences d'échappement et entièreté-backslash tout et choisir ce que vous-même ou analyser à remplacer, dans votre propre code.
Si nous voulons faire tout traitement ou analyse syntaxique significatif sur les lignes de texte, nous aurons besoin d'utiliser un script.
La lecture Lignes partir d'un fichier avec un script
Voici notre script. Il est appelé « script1.sh. »
#! / Bin / bash
Compteur = 0
lorsque IFS = '' lire -r LinefromFile [116 ] || [[ -n " $ {} LinefromFile " ] ] faire
(( Compteur ++ ))
écho "ligne Accès $ contre : $ {LinefromFile} " [9 ]
fait & lt; " 1 $ "
Nous définissons une variable appelée
Contrer
à zéro, alors nous définissons notre
tandis que
boucle.
La première déclaration de la ligne tandis que
Ifs = ''
.
Ifs
représente le séparateur de champ interne. Il contient des valeurs que Bash utilise pour identifier les limites de mots. Par défaut, la commande de lecture enregistre les espaces de pointe et de suivi. Si nous voulons lire les lignes du fichier exactement comme ils sont, nous devons définir
Ifs
être une chaîne vide.
Nous pourrions mettre cela une fois en dehors de la boucle, comme nous définissons la valeur de
Contrer
. Mais avec des scripts plus complexes, en particulier ceux avec de nombreuses fonctions définies par l'utilisateur, il est possible que
Ifs
pourrait être réglé sur différentes valeurs ailleurs dans le script. Assurer que
Ifs
est réglé sur une chaîne vide à chaque fois la
tandis que
La boucle itérate garantit que nous savons quel sera son comportement.
Nous allons lire une ligne de texte dans une variable appelée
Linefomfile
. Nous utilisons le
-R
(Read Backslash en tant que caractère normal) option pour ignorer les backslashes. Ils seront traités comme tout autre personnage et ne recevront aucun traitement spécial.
Il y a deux conditions qui satisferont la
tandis que
boucle et permettre au texte de traiter par le corps de la boucle:
-
Lire -r linefromfile: Lorsqu'une ligne de texte est lue avec succès dans le fichier, lelirecommande envoie un signal de réussite à latandis que, et letandis queLa boucle passe le flux d'exécution au corps de la boucle. Notez que lelirecommande doit voir un nouveau caractère à la fin de la ligne de texte afin de considérer cela une lecture réussie. Si le fichier n'est pas un Posix fichier texte conforme, le La dernière ligne peut ne pas inclure un caractère de nouvelle ligne . Si lalirela commande voit la Marqueur de fin de fichier (EOF) avant que la ligne ne soit terminée par une nouvelle ligne, elle sera ne pas Traitez-le comme une lecture réussie. Si cela se produit, la dernière ligne de texte ne sera pas transmise au corps de la boucle et ne sera pas traitée. -
[-N "$ {linefromfile}"]: Nous devons faire des travaux supplémentaires pour gérer des fichiers compatibles non posix. Cette comparaison vérifie le texte qui est lu dans le fichier. S'il n'est pas terminé avec un personnage de nouvelle ligne, cette comparaison retourne toujours le succès à latandis queboucle. Cela garantit que tous les fragments de ligne de fuite sont traités par le corps de la boucle.
Ces deux clauses sont séparées par l'opérateur logique "
||
"Alors que si
Soit
La clause renvoie le succès, le texte récupéré est traité par le corps de la boucle, qu'il existe un caractère nouveau ou non.
Dans le corps de notre boucle, nous incrémentons la
Contrer
variable par un et en utilisant
écho
envoyer une sortie à la fenêtre du terminal. Le numéro de ligne et le texte de chaque ligne sont affichés.
Nous pouvons toujours utiliser notre truc de redirection pour rediriger un fichier en boucle. Dans ce cas, nous redirigeons 1 $, une variable qui détient le nom du premier paramètre de ligne de commande transmis au script. En utilisant cette truc, nous pouvons facilement passer au nom du fichier de données que nous souhaitons que le script fonctionne.
Copiez et collez le script dans un éditeur et enregistrez-le avec le nom de fichier «script1.sh». Utilisez le
chmod
commander
Pour le rendre exécutable
.
chmod + x script1.sh
Voyons ce que notre script marque du fichier texte Data2.txt et les barres anti-backs contenues de l'intérieur.
./ script1.sh data2.txt
Chaque caractère de la ligne est affiché Verbatim. Les backslashes ne sont pas interprétées comme des caractères d'évacuation. Ils sont imprimés en caractères réguliers.
Passer la ligne à une fonction
Nous faisons toujours écho au texte à l'écran. Dans un scénario de programmation du monde réel, nous serions probablement sur le point de faire quelque chose de plus intéressant avec la ligne de texte. Dans la plupart des cas, il s'agit d'une bonne pratique de programmation pour traiter le traitement ultérieur de la ligne dans une autre fonction.
Voici comment nous pourrions le faire. C'est "script2.sh."
Nous définissons notre
Contrer
variable comme avant, puis nous définissons une fonction appelée
processus_line ()
. La définition d'une fonction doit apparaître
avant
La fonction est appelée pour la première fois dans le script.
Notre fonction va être adoptée la ligne de texte nouvellement lu dans chaque itération de la
tandis que
boucle. Nous pouvons accéder à cette valeur dans la fonction en utilisant le
1 $
variable. S'il y avait deux variables passées à la fonction, nous pourrions accéder à ces valeurs en utilisant
1 $
et
2 $
, et ainsi de suite pour plus de variables.
Le
hile
La boucle est principalement la même. Il n'y a qu'un seul changement à l'intérieur du corps de la boucle. Les
écho
la ligne a été remplacée par un appel à la
processus_line ()
fonction. Notez que vous n'avez pas besoin d'utiliser les supports «()» au nom de la fonction lorsque vous l'appelez.
Le nom de la variable tenant la ligne de texte,
Linefomfile
, est enveloppé de guillemets lorsqu'il est transmis à la fonction. Cela s'adresse aux lignes qui ont des espaces en eux. Sans les guillemets, le premier mot est traité comme
1 $
par la fonction, le deuxième mot est considéré comme étant
2 $
, etc. L'utilisation de marques de devis garantit que toute la ligne de texte est traitée, tout à fait
1 $
. Notez que c'est
ne pas
le même
1 $
qui détient le même fichier de données transmis au script.
Parce que
Contrer
a été déclaré dans le corps principal du script et non à l'intérieur d'une fonction, elle peut être référencée à l'intérieur du
processus_line ()
fonction.
Copiez ou tapez le script ci-dessus dans un éditeur et enregistrez-le avec le nom de fichier "script2.sh". Rendre exécutable avec
chmod
:
chmod + x script2.sh
Maintenant, nous pouvons l'exécuter et passer dans un nouveau fichier de données "Data3.txt." Cela a une liste des mois dedans et une ligne avec de nombreux mots dessus.
Janvier février Mars . . octobre Novembre \ nmore texte "à la fin de la ligne" Décembre
Notre commande est:
./ script2.sh data3.txt
Les lignes sont lues dans le fichier et passa une par une à la
processus_line ()
fonction. Toutes les lignes sont correctement affichées, y compris l'impair avec le backpace, les guillemets et les mots multiples de celui-ci.
Les blocs de construction sont utiles
Il y a un train de pensée qui dit qu'un idiome doit contenir quelque chose d'unique à cette langue. Ce n'est pas une conviction que je souscris à. Ce qui est important, c'est qu'il fait bon usage de la langue, est facile à retenir et fournit une manière fiable et robuste de mettre en œuvre certaines fonctionnalités de votre code.