Comment puis-je parcourir les lignes dans un fichier externe avec shell? [dupliquer]

Doublon Possible:
boucler le contenu d'un fichier dans Bash?

J'ai un fichier avec une liste de noms. J'ai besoin de parcourir tous les noms de ce fichier à partir d'un fichier externe avec un script shell. Comment puis-je le faire?

Exemple de fichiers:

Scripts/noms.txt

alison
barb
charlie
david

Scripts/script.sh

NAMES="" #names from names.txt file
for NAME in $NAMES; do
    echo "$NAME"
done

Comment puis-je faire exploser les noms.fichier txt dans un tableau dans un autre script shell?

27
demandé sur Community 2012-07-05 21:54:40

5 réponses

Une façon serait:

while read NAME
do
    echo "$NAME"
done < names.txt

Modifier: notez que la boucle est exécutée dans un sous-shell, donc toutes les variables modifiées seront locales, sauf si vous les déclarez avec declare en dehors de la boucle.

Dennis Williamson est droit. Désolé, a dû utiliser des constructions canalisées trop souvent et a été confus.

55
répondu smocking 2012-07-05 19:20:40

Vous aurez envie d'utiliser la commande 'read'

while read name
do
    echo "$name"
done < names.txt

Notez que "$ name " est entre guillemets - si ce n'est pas le cas, il sera divisé en utilisant les caractères de $IFS comme délimiteurs. Cela ne sera probablement pas remarqué si vous faites juste écho à la variable, mais si votre fichier contient une liste de noms de fichiers que vous voulez copier, ceux-ci seront décomposés par $IFS si la variable n'est pas cotée, ce qui n'est pas ce que vous voulez ou attendez.

Si vous voulez utiliser L'approche de Mike Clark (chargement dans une variable plutôt que d'utiliser la lecture), vous pouvez le faire sans l'utilisation de cat:

NAMES="$(< scripts/names.txt)" #names from names.txt file
for NAME in $NAMES; do
    echo "$NAME"
done

Le problème avec ceci est qu'il charge le fichier entier dans $NAMES, lorsque vous le relisez, vous pouvez soit obtenir le fichier entier (si cité) ou le fichier décomposé par $IFS, s'il n'est pas cité. Par défaut, cela vous donnera des mots individuels, pas des lignes individuelles. Donc, si le nom "Mary Jane" apparaissait sur une ligne, vous obtiendriez "Mary" et "Jane" comme deux noms distincts. L'utilisation de read contournera cela... bien que vous pourrait aussi changer la valeur de $IFS

13
répondu Barton Chittenden 2012-07-05 18:35:42
cat names.txt|while read line; do
    echo "$line";
done
7
répondu arnaud576875 2012-07-05 17:58:46

Je sais que les puristes vont détester cette méthode, mais vous pouvez cat le fichier.

NAMES=`cat scripts/names.txt` #names from names.txt file
for NAME in $NAMES; do
   echo "$NAME"
done
5
répondu Mike Clark 2012-07-05 17:58:27

Cela pourrait fonctionner pour vous:

cat <<\! >names.txt
> alison
> barb
> charlie
> david
> !
OIFS=$IFS; IFS=$'\n'; NAMES=($(<names.txt)); IFS=$OIFS
echo "${NAMES[@]}"
alison barb charlie david
echo "${NAMES[0]}"
alison
for NAME in "${NAMES[@]}";do echo $NAME;done
alison
barb
charlie
david
2
répondu potong 2012-07-05 19:19:07