Bash: Βρόχος επανάληψης σε εύρος αριθμών όπου μεταβλητές ορίζουν την αρχή ή το τέλος

dimitris | Πέμ, 09/25/2014 - 14:23 | 3'

Χρειάστηκε να κάνω iteration σε ένα range από ακεραίους αλλά το τέλος της επανάληψης να σηματοδοτείται από μεταβλητή, οπότε ψάχνοντας βρήκα τους παρακάτω 4 τρόπους. Με ενδιέφερε και η ταχύτητά τους, ειδικά αν το εύρος είναι πολύ μεγάλο, οπότε χρησιμοποίησα την time για να τους αντιπαραβάλλω για 1 εκατομμύριο τιμές.

O πιο απλός τρόπος είναι με χρήση της seq η οποία όμως υπάρχει μόνο στα GNU/Linux συστήματα (σε εμένα ήταν και το πιο γρήγορο)

end=1000000; time for i in $(seq 1 $end); do :; done

real    0m2.215s
user    0m2.198s
sys     0m0.028s

Η δεύτερη και πιο OS-agnostic λύση είναι με χρήση της integer αριθμητικής του bash - είναι όμως και πιο χρονοβόρα όπως φαίνεται:
 

typeset -i i END
let END=1000000  i=1;
i=1; time while ((i<END)); do :; let i++; done

real    0m4.762s
user    0m4.748s
sys     0m0.001s

Η τρίτη λύση είναι με την eval που τα πηγαίνει πιο καλά:

time for i in $(eval echo "{1..$END}"); do :;done

real    0m3.011s
user    0m2.938s
sys     0m0.092s

Και τέλος, για όσους την βρίσκουν με C/C++ υπάρχει και ο τελεστής for στο Bash που κάνει αυτόματα χρήση integer arithmetic:

END2=1000000; time for ((j=1;j<=END2;++j)); do :; done

real    0m3.337s
user    0m3.302s
sys     0m0.009s

 

Αν θέλετε, προτείνετε πιο γρήγορους τρόπους. Γηράσκω αεί διδασκόμενος :)

BTW, οι δοκιμές έγιναν σε Kubuntu 64bit με i5-4440 CPU @ 3.10GHz.

 

Περισσότερα tutorials για Bash:

Εισαγωγή στο Bash: Ροές και pipes

Bash: Βρόχος επανάληψης σε εύρος αριθμών όπου μεταβλητές ορίζουν την αρχή ή το τέλος

Bash: Πως εκτελούμε μια εντολή Χ φορές στη σειρά με την for

Bash: Κωδικοί εξόδου και έλεγχος ροής

Scripting: Όταν το GUI δέν επαρκεί

Bash: Επεξεργασία κειμένου με Regular Expressions και άλλα κόλπα

Δώσε αστέρια!

MO: 5 (ψήφοι: 2)