2014-04-18 7 views
13

Come modificare il codice seguente in modo che quando viene eseguito in zsh espanda $things e iterates attraverso di loro uno alla volta?Come eseguire un'iterazione tramite stringa una parola alla volta in zsh

things="one two" 

for one_thing in $things; do 
    echo $one_thing 
done 

Voglio l'output di essere:

one 
two 

Ma, come scritto sopra, emette:

one two 

(sto cercando il comportamento che si ottiene quando si esegue il sopra il codice in bash)

+1

Ciò significa che 'zsh' non sta separando le parole' $ things' quando è l'elenco di un ciclo 'for'? Sta entrando nel corpo del ciclo solo una volta? La risposta, dopo aver combattuto attraverso lo script di configurazione, è "Sì". Scratch 'zsh' dalla lista delle shell utilizzabili; è troppo simile a shell non POSIX. Non posso nemmeno preoccuparmi di iniziare a pensare a come potrebbe essere configurabile lavorare normalmente. –

risposta

23

Per visualizzare il comportamento compatibile con la shell Bourne, è necessario impostare l'opzione SH_WORD_SPLIT:

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

for one_thing in $things; do 
    echo $one_thing 
done 

produrrebbe:

one 
two 

Tuttavia, si consiglia di utilizzare una matrice per la produzione di suddivisione delle parole, ad esempio,

things=(one two) 

for one_thing in $things; do 
    echo $one_thing 
done 

Si consiglia inoltre di fare riferimento a:

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

+0

Invece di impostare 'shwordsplit' globalmente, puoi abilitare la divisione delle parole in stile' sh' (usando 'IFS', ovviamente) per un singolo parametro con' $ {= cose} '. – chepner

+0

@chepner, come sarebbe? Ho provato 'IFS = ''; per una cosa in $ {= cose}; do', ma ha un errore di "sostituzione errata" –

+0

@RobBednark Perché non usi un array? – devnull

4

È possibile utilizzare il flag di espansione variabile z fare suddivisione delle parole su una variabile

things="one two" 

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

Per saperne di più su questa e altre bandiere variabili in man zshexpn, in "Parametri di espansione Flags."

-1

È possibile assumere il separatore di campo interno (IFS) su bash per essere \ x20 (spazio). Questo rende i seguenti lavori:

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

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

Con questo in mente è possibile implementare questo in molti modi diversi basta manipolare l'IFS; anche su stringhe multi-linea.

Problemi correlati