2013-09-16 15 views
5

Wiem, jak wykonać pętlę w bashu, która zwiększa się o jeden za każdym razem, ale mówię, że mam zakres od 1 do 773 i chcę wyprowadzić zakres z pętli, aby uzyskać dwa zmienne w każdej iteracji. Pierwszy będzie 1, a drugi będzie powiedzieć 19. W drugiej iteracji pierwszy będzie 20, a drugi 39.Przyrost w pętli bash o ustawioną kwotę

Ive gra z czymś takim:

for start in {1..773} 
do  
start=$(($start+20)) 
end=$(($start+20)) 
echo $start ## 
echo $end 
done 

Pożądany efekt pętli:

1. $start = 1 and $end = 19 
2. $start = 20 and $end = 39 
3. $start = 40 and $end = 59 
etc 

Ale to nie w porządku. Chcę wyprowadzić te dwie zmienne do serii skryptów, aby R działał szybciej, więc jeśli rozwiązania typu non bash (np. Awk) są łatwiejsze, to też jest fajne, jeśli prosty> wyśle ​​plik.

Dzięki!

+4

Pętla nie jest zgodne ze startów. 1 staje się 20 (+19), a następnie 20 staje się 40 (+20). Nie jest to możliwe w przypadku ciągłej pętli. – konsolebox

Odpowiedz

5

Jeśli chcesz wydrukować zakresy w obrębie 773, można zrobić tak

#!env bash 
start=1 
end=19 
for counter in {1..773} 
do 
    echo $counter. "\$start = " $start " and \$end = " $end 
    if [[ $start -eq 1 ]]; 
    then 
     start=0 
    fi 
    start=$(($start+20)) 
    end=$(($end+20)) 
    if [[ $end -ge 773 ]]; 
    then 
     break 
    fi 
done 

Wyjście

1. $start = 1 and $end = 19 
2. $start = 20 and $end = 39 
3. $start = 40 and $end = 59 
4. $start = 60 and $end = 79 
5. $start = 80 and $end = 99 
6. $start = 100 and $end = 119 
7. $start = 120 and $end = 139 
8. $start = 140 and $end = 159 
9. $start = 160 and $end = 179 
10. $start = 180 and $end = 199 
11. $start = 200 and $end = 219 
12. $start = 220 and $end = 239 
13. $start = 240 and $end = 259 
14. $start = 260 and $end = 279 
15. $start = 280 and $end = 299 
16. $start = 300 and $end = 319 
17. $start = 320 and $end = 339 
18. $start = 340 and $end = 359 
19. $start = 360 and $end = 379 
20. $start = 380 and $end = 399 
21. $start = 400 and $end = 419 
22. $start = 420 and $end = 439 
23. $start = 440 and $end = 459 
24. $start = 460 and $end = 479 
25. $start = 480 and $end = 499 
26. $start = 500 and $end = 519 
27. $start = 520 and $end = 539 
28. $start = 540 and $end = 559 
29. $start = 560 and $end = 579 
30. $start = 580 and $end = 599 
31. $start = 600 and $end = 619 
32. $start = 620 and $end = 639 
33. $start = 640 and $end = 659 
34. $start = 660 and $end = 679 
35. $start = 680 and $end = 699 
36. $start = 700 and $end = 719 
37. $start = 720 and $end = 739 
38. $start = 740 and $end = 759 
+0

Wiedziałem, o co prosiłem, mam prostą odpowiedź, ale twoja działa najlepiej. Zaczyna się od 1 i zawiera pełny zakres, którego nie udzielają inne odpowiedzi. Stukrotne dzięki! – cianius

11

Twoje wymagania nie są całkowicie jasne, ale ponownie używasz nazw zmiennych.

jeśli mogę to zrobić:

for index in {1..773} 
do  
    start=$(($index+20)) 
    end=$(($start+20)) 
    echo $start ## 
    echo $end 
done 

ja dostać coś, co przypomina pożądany rezultat. obserwuj jak zmieniłem nazwę zmiennej pętli od początku do indeksu.

PS: jeśli chcesz zmienić wielkość skoku (aka „przyrost”) w pętli, po prostu zrobić to tak:

#!/bin/bash 
for i in {0..10..2} 
    do 
    echo "Welcome $i times" 
done 

To będzie zwiększać w odstępach co 2, co chcesz używać 20 tutaj. To da Ci 1, 21, 41, ... jako wartość. Aby uzyskać więcej informacji, patrz http://www.cyberciti.biz/faq/bash-for-loop/.

+2

Najpierw sprawdź wersję "bash". Obsługa słowa "{x..y..z}" została dodana w wersji 4.0 (możliwe, że 4.1, dziennik zmian o tym nie wspomina i nie mam instancji 4.0 do sprawdzenia). – chepner

2

Oto jeden ze sposobów, aby to zrobić:

step=20 
last=773 

for ((i = 0; i <= $last; i += $step)) 
do 
    start=$i 

    end=$(($i + (($step - 1)))) 

    if (($end > $last)) 
    then 
     end=$last 
    fi 

    echo "\$start: $start" 
    echo "\$end: $end" 
done 

Jest to w zasadzie tylko prosty do pętli.

5

Można użyć polecenia seq

for start in `seq 1 20 700` 
do  
    echo $start $(($start+19)) 
done 

Wykorzystanie seq jest:

$ seq --help 
Usage: seq [OPTION]... LAST 
    or: seq [OPTION]... FIRST LAST 
    or: seq [OPTION]... FIRST INCREMENT LAST 
Print numbers from FIRST to LAST, in steps of INCREMENT. 
+1

Powinny wspomnieć, że środkowa liczba to przyrost. –

+1

Dzięki @AbdullahAlMamun. Edytowano odpowiedź. – ztik

3

Jest to jeden ze sposobów, aby to zrobić z konsekwentnych wyjść:

for ((i = 1, start = 1, end = 19; i <= 773; ++i, start += 20, end += 20)); do 
    echo "$i. \$start = $start and \$end = $end" 
done 

wyjściowa:

1. $start = 1 and $end = 19 
2. $start = 21 and $end = 39 
3. $start = 41 and $end = 59 
4. $start = 61 and $end = 79 

Albo

for ((i = 1, start = 1, end = 19; i <= 773; ++i, start += 20, end += 20)); do 
    echo "$i. \$start = $start and \$end = $end" 
done 

wyjściowa:

1. $start = 1 and $end = 20 
2. $start = 21 and $end = 40 
3. $start = 41 and $end = 60 
4. $start = 61 and $end = 80 

Inna:

for ((i = 1, start = 0, end = 19; i <= 773; ++i, start += 20, end += 20)); do 
    echo "$i. \$start = $start and \$end = $end" 
done 

wyjściowa:

1. $start = 0 and $end = 19 
2. $start = 20 and $end = 39 
3. $start = 40 and $end = 59 
4. $start = 60 and $end = 79 

W ten sposób można mieć dwie zmienne.

4

chyba że jestem brakuje czegoś, można po prostu zrobić:

for ((s=0,e=19; e<773; s+=20,e+=20)); do 
    echo $s "-" $e 
done 

WYJŚCIE:

0 - 19 
20 - 39 
40 - 59 
60 - 79 
80 - 99 
100 - 119 
120 - 139 
140 - 159 
160 - 179 
180 - 199 
200 - 219 
220 - 239 
240 - 259 
260 - 279 
280 - 299 
300 - 319 
320 - 339 
340 - 359 
360 - 379 
380 - 399 
400 - 419 
420 - 439 
440 - 459 
460 - 479 
480 - 499 
500 - 519 
520 - 539 
540 - 559 
560 - 579 
580 - 599 
600 - 619 
620 - 639 
640 - 659 
660 - 679 
680 - 699 
700 - 719 
720 - 739 
740 - 759 
4

Nikt nie zaproponował while pętla

start=0 step=20 end=$((step - 1)) 
while ((end < 773)); do 
    echo "$start - $end" 
    ((start += step, end += step)) 
done 

Produkuje

0 - 19 
20 - 39 
40 - 59 
... 
720 - 739 
740 - 759 

Oczywiście pętli while może być zapisana jako pętli for:

for ((start=0, step=20, end=step-1; end < 773; start+=step, end+=step)); do ...