2008-09-17 9 views

Antwort

45

schlag (im Gegensatz zu POSIX sh) unterstützt Arrays:

fruits=(apple orange kiwi "dried mango") 
for fruit in "${fruits[@]}"; do 
    echo "${fruit}" 
done 

Dies hat den Vorteil, dass die Feldelemente IFS Räume oder andere Mitglieder $ enthalten können; Solange sie korrekt als separate Elemente eingefügt wurden, werden sie auf die gleiche Weise ausgelesen.

+0

Ich sehe auch "getrocknete" und "Mango" -Drucke als separate Früchte hier, mit bash auf Debian und Mac OS X. Das scheint also nicht gegen die IFS für mich zu schützen. :-( – emk

+0

emk, das ist mein Schlechter - Ich habe auf zsh getestet, nicht bash; behoben seit. –

+0

Ich kann bestätigen, dass dies funktioniert. – emk

4
 
for i in apple orange kiwi 
do 
    echo $i 
done 
+0

'echo" $ i "' innerhalb der Schleife - ohne die Anführungszeichen, tut dies glob Expansion und IFS Spaltung auf den Elementen, macht 'foo bar' die gleiche wie' foo bar' und machen '* .txt' echo alle übereinstimmenden Dateien im aktuellen Verzeichnis, anstatt ein Literal '* .txt' auszulösen. –

11

So:

FRUITS="apple orange kiwi" 
for FRUIT in $FRUITS; do 
    echo $FRUIT 
done 

Hinweis dies wird nicht funktionieren, wenn es Leerzeichen in den Namen Ihrer Früchte sind. In diesem Fall siehe stattdessen this answer, was etwas weniger portabel, aber viel robuster ist.

+0

In Bash unter Mac OS X scheint es, als brauche ich entweder einen Semikolon oder einen Zeilenumbruch vor dem 'tun'. – emk

+0

Ja, Sie brauchen das Semikolon, es sei denn, Ihr "do" befindet sich in einer neuen Zeile. Außerdem muss $ IFS einen Speicherplatz enthalten, damit dies funktioniert. –

+0

abhängig von IFS während der Iteration (anstatt nur Zuweisung) ist schlecht juju, was diese Antwort suboptimal. Zugegeben, meins hat es auch getan - ich habe auf zsh getestet, seither für bash. –

6

Jetzt, da die Antwort, die ich mag, als die richtige Antwort akzeptiert wurde, werde ich jetzt in ein anderes Thema einsteigen: wie man IFS für persönlichen Gewinn verwendet. :-P

fruits="apple,orange,kiwifruit,dried mango" 
(IFS=, 
for fruit in $fruits; do 
    echo "$fruit" 
done) 

ich den Code in Klammern gesetzt haben, so dass die IFS Änderung in seine eigene subprocess isoliert wird; Am Ende des Klammerabschnitts wird IFS auf den alten Wert zurückgesetzt. :-)

+0

Wenn ich 'fruits = (Apfel orange" Kiwis ") probiere, teilt bash während der Schleife" kiwi "und" fruit "in separate Einheiten auf. Solange du für/in bist, wirst du vom IFS verbrannt. Aber 'echo $ {fruits [2]}' macht das Richtige, was schön ist. – emk

+0

Siehe http://stackoverflow.com/questions/78592/what-isa-good-equivalent-to-perl-lists-in-bash#78631 für eine Version dieses Codes, die funktioniert. – emk

+0

Danke für Feedback! Fest. –