Per loop in zsh e bash


57

Ho notato che ci sono due modi alternativi di costruire loop in zsh :

  1. for x (1 2 3); do echo $x; done
  2. for x in 1 2 3; do echo $x; done

Entrambi stampano:

1
2
3

La mia domanda è: perché le due sintassi? È $xl'iterazione attraverso un diverso tipo di oggetto in ciascuno di essi?

Fa bash fare una simile distinzione?

Addendum:

Perché funziona quanto segue ?:

#!/bin/zsh
a=1
b=2
c=5    

d=(a b c)    
for x in $d; do print $x;done

ma questo no ?:

#!/bin/zsh
a=1
b=2
c=5

d=(a b c)    
# It complains with "parse error near `$d'"
for x $d; do print $x;done 

5
per l'esempio che "non funziona", che è uno stile csh per loop, mancano le parentesi. for x ($d); do print $x; donefunzionerà e corrisponderà alla prima sintassi che hai elencato all'inizio della domanda.
Tim Kennedy,

1
È così folle - che quelle due affermazioni - in effetti non "lavorino allo stesso modo". Non riesco letteralmente a pensarci bene! Ho bisogno di fumare un po 'di quello che stavano fumando quei disegnatori di conchiglie, lol.
alex gray

Attento, c'è di più in questa storia di quanto appaia inizialmente. Ti invito a controllare la mia risposta.
Jasonleonhard,

Non ho visto nessun altro menzionarlo, ma entrambe le forme consentono l'omissione di do / done: for i ({0..4..2}) for j ({a..c}) echo "($i,$j)"= {0,2,4}x{a,b,c}. I punti e virgola si applicano al ciclo più esterno e i reindirizzamenti si applicano al più interno, e se è necessario modificarlo, sono necessari solo parentesi graffe: for i ({0..4..2}) { for j ({a..c}) echo "($i,$j)" } | cat -n= {1,...,9}*({0,2,4}x{a,b,c}). Ovviamente puoi combinare i loop con l'espansione zsh:for i ("("{0..4..2}","{a..c}")") echo $i
John P

Risposte:


59

Diverse forme di comandi complessi come i loop hanno forme alternative in zsh. Queste forme sono per lo più ispirate alla shell C , che era abbastanza comune quando zsh era giovane ma ora è scomparso. Queste forme alternative si comportano esattamente come le forme normali, sono solo una sintassi diversa. Sono leggermente più corti, ma meno chiari.

Il modulo standard per il forcomando è for x in 1 2 3; do echo $x; donee il modulo standard per il whilecomando è while test …; do somecommand; done. Ksh, bash e zsh hanno una forma alternativa di for: for ((i = 0; i < 42; i++)); do somecommand; done, che imita i forloop di linguaggi come Pascal o C, per enumerare i numeri interi. Altre forme esotiche che esistono in zsh sono specifiche di zsh (ma spesso ispirate a csh).


Grazie mille @Guilles. Sono comunque un po 'confuso. A quale forma è quella specifica zsh? Inoltre, ho aggiunto un esempio alla fine del mio PO in cui non riesco a capire come tradurre tra le sintassi. Se la differenza è solo sintassi, come devo correggere il secondo script nell'addendum per farlo funzionare?
Amelio Vazquez-Reina,

3
@intrpc Vedi la mia risposta aggiornata. Come per il tuo ultimo esempio, non funziona perché hai scritto for x $de zsh si aspetta ino (dove hai scritto $d. I segni di punteggiatura e le parole riservate non possono provenire da un'espansione variabile, devono essere analizzati prima che la shell possa iniziare sulle espansioni variabili.
Gilles 'SO- smetti di essere malvagio' il

@intrpc entrambi sono specifici di zsh. zsh è stato progettato specificamente per supportare la sintassi di bourne, korn e c-shell, in quanto è un ibrido di tutti e tre.
Tim Kennedy,

1
@pseyfert Funziona, ma non ha alcun vantaggio rispetto ai moduli che mostro: è meno portatile del for (( … ))modulo e utilizza molta memoria se 3 è grande.
Gilles 'SO- smetti di essere malvagio' il

1
@ alpha_989 Nella sintassi sh-like, è necessario dodopo ));. Zsh accetta anche un'altra sintassi in for ((…)); COMMANDcui COMMANDè un singolo comando. Ecco perché accetta for ((i = 1; i<100; i++)); ghi show $i | grep "log". Quando vede donedopo questo, si lamenta perché non c'era dofine. Vedere "Moduli alternativi per comandi complessi" nel manuale .
Gilles 'SO- smetti di essere malvagio' il
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.