Je lisais ce fil: Comment faire une boucle sur les lignes d'un fichier?
Qu'est-ce que c'est IFS? Et quelle est son utilisation dans le contexte de for-loops?
Je lisais ce fil: Comment faire une boucle sur les lignes d'un fichier?
Qu'est-ce que c'est IFS? Et quelle est son utilisation dans le contexte de for-loops?
Réponses:
IFSreprésente - c'est un caractère qui sépare les champs. Dans l'exemple que vous avez publié, il est défini sur un nouveau caractère de ligne ( ); donc après l'avoir défini, traitera le texte ligne par ligne. Dans cet exemple, vous pouvez modifier la valeur de (en une lettre que vous avez dans votre fichier d'entrée) et vérifier comment le texte sera divisé.InputInternal Field Separator\nforIFS
BTW, d'après la réponse que vous avez publiée, la deuxième solution est celle recommandée ...
Comme @jasonwryan remarqué, ce n'est pas Inputmais Internal. Le nom Inputvient d' awkoù il y a aussi OFS- Output Field Separator.
Sétait pour separator dans le shell Bourne d'où il provenait. Dans le shell Korn et la plupart des autres shell de type Bourne comme cela a été spécifié par POSIX, le Sest pour le délimiteur (étirez un peu votre imagination) car A::B:par exemple est divisé en "A", "" et "B" (sans supplément ""). C'est différent de awk's FSou du sdrapeau d'expansion des paramètres de zsh.
IFSn'est pas directement lié au bouclage, il est lié au fractionnement de mots. IFSdétermine indirectement comment la sortie de la commande est divisée en morceaux sur lesquels la boucle itère.
Lorsque vous avez une substitution de variable non protégée $fooou une substitution de commande $(foo), il y a deux cas:
"$foo", ou dans une affectation de variable x=$foo, la chaîne résultant de la substitution est utilisée telle quelle.$IFSest considéré comme un séparateur de mots. Par exemple, IFS=":"; foo="12:34::78"; echo $fooimprime 12 34 78(avec deux espaces entre 34et 78, car il y a un mot vide).foo="*"; echo $fooimprime la liste des fichiers dans le répertoire courant.Pour les boucles, comme beaucoup d'autres contextes, attendez-vous à une liste de mots. Donc
for x in $(foo); do …
se décompose $(foo)en mots et traite chaque mot comme un motif global. La valeur par défaut de IFSest espace, tabulation et nouvelle ligne , donc si fooimprime deux lignes hello worldet que howdyle corps de la boucle est exécuté avec x=hello, puis x=worldet x=howdy. Si IFSest explicitement modifié pour ne contenir qu'une nouvelle ligne, la boucle est exécutée pour hello worldet howdy. Si IFSest changé pour être o, alors la boucle est exécutée pour hell, w, rldh(où est un caractère de saut de ligne) et wdy.
"IFS indirectly determines how ..."?
IFS(directement) détermine comment la sortie de la substitution de commande est décomposée, ce qui détermine ensuite (indirectement) ce que la boucle boucle.
De man bash
IFS Séparateur de champ interne utilisé pour le fractionnement de mots après expansion et pour diviser des lignes en mots avec la commande intégrée read. La valeur par défaut est "<espace> <tab> <newline>".
C'est l'une des variables internes de Bash. Il détermine comment Bash reconnaît les champs ou les limites des mots lorsqu'il interprète les chaînes de caractères.
Par défaut, il s'agit d'espaces (espace, tabulation et nouvelle ligne), mais il peut être modifié, par exemple, pour analyser un fichier de données séparé par des virgules.
En plus des excellentes réponses précédentes, permettez-moi d'ajouter que IFS est très utile pour une analyse efficace et portable dans des cas simples en combinaison avec set . Efficace, car évite d'utiliser des sous-coquilles et des outils de frai comme grep ou sed:
resolutions="640x480,320x240"
xIFS=$IFS
IFS=','
for res in $resolutions; do
xxIFS=$IFS
IFS='x'
set -- $res
width=$1
height=$2
# handle width and height
IFS=$xxIFS
done;
IFS=$xIFS
Notez simplement que nous devons stocker et récupérer la valeur précédente d' IFS pour éviter les ruptures indésirables dans d'autres parties du script.