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.