2014-04-18 13 views
13

Wie ändere ich den folgenden Code, so dass bei der Ausführung in zsh es erweitert $things und iteriert sie einzeln nacheinander?Wie durchstreichen Sie ein Wort nach dem anderen in zsh

things="one two" 

for one_thing in $things; do 
    echo $one_thing 
done 

Ich mag die Ausgabe sein:

one 
two 

Aber wie oben geschrieben, es gibt:

one two 

(Ich bin für das Verhalten suchen, die Sie erhalten, wenn der Lauf Über den Code in bash)

+1

Bedeutet das, dass 'zsh' nicht' 'sachen' ist, wenn es die Liste einer 'for' Schleife ist? Tritt es nur einmal in den Körper der Schleife ein? Antwort, nach dem Kämpfen durch das Konfigurationsskript, ist "Ja". Scratch 'zsh' aus der Liste der verwendbaren Shells; das ist einfach zu wenig POSIX-Shell. Ich kann mich nicht einmal darüber aufregen, wie konfigurierbar es ist, "normal" zu arbeiten. –

Antwort

23

Um das Verhalten mit Bourne-Shell kompatibel zu sehen, müssen Sie die Optionfestlegen:

setopt shwordsplit  # this can be unset by saying: unsetopt shwordsplit 
things="one two" 

for one_thing in $things; do 
    echo $one_thing 
done 

produzieren würde:

one 
two 

Es ist jedoch ein Array zu verwenden zur Herstellung Wort Spaltung, zB

things=(one two) 

for one_thing in $things; do 
    echo $one_thing 
done 

Sie wollen auch beziehen empfohlen wird zu:

3.1: Why does $var where var="foo bar" not do what I expect?

+0

Statt 'shwordsplit' global zu setzen, können Sie' sh'-Stil Wortteilung (mit 'IFS', natürlich) für einen einzigen Parameter mit' $ {= dings} 'aktivieren. – chepner

+0

@chepner, wie würde das aussehen? Ich habe versucht "IFS ="; für one_thing in $ {= dinge}; do' aber bekam einen 'bad substitution' Fehler –

+0

@RobBednark Warum verwendest du kein Array? – devnull

4

Sie können die z Flagvariable Expansion verwenden Wort Spaltung auf eine Variable

things="one two" 

for one_thing in ${(z)things}; do 
    echo $one_thing 
done 

Lesen Sie mehr über diese und andere variable Flaggen in man zshexpn, unter zu tun "Parameter Expansion Flags."

-1

Sie können annehmen, dass der interne Feldtrenner (IFS) in bash zu \ x20 (Leerzeichen) gehört. Dies macht folgende Arbeiten:

#IFS=$'\x20' 
#things=(one two) #array 
things="one two" #string version 

for thing in ${things[@]} 
do 
    echo $thing 
done 

Vor diesem Hintergrund Sie diese auf viele verschiedene Arten implementieren können nur die IFS Manipulation; sogar bei mehrzeiligen Strings.