Próbowałem stworzyć bardzo prosty skrypt bash, aby wyświetlić wszystkie wielokrotności pięciu między 375 a 3500 (375, 380, 385 ...). Jedną z rzeczy, które próbowałem i nie działałem, są:
for i in {375..3500}
do
echo $i
(($i += 5))
done
Po pewnym czasie poddałem się i napisałem to w języku BASIC w około 15 sekund:
10 count = 375
20 print count
30 count = count+5
40 if count < 3500 then goto 20
Jak mogę zrobić mój program BASIC w skrypcie bash?
Odpowiedzi:
Alternatywnie można zastosować tradycyjny styl pętli typu C:
Jest to być może mniej jasne niż użycie seq, ale nie powoduje żadnych podprocesów. Chociaż odkąd znam C, nie miałbym żadnych trudności ze zrozumieniem tego, ale YMMV.
źródło
dash
go nie obsługuje. @ChrisDown - Nie ma powodu, dla którego „POSIX sh” musi oznaczać „brak seq”. Ale tak, oczywiście, przeoczyłem fakt, że seq nie jest określony przez POSIX.Ponieważ i tak używasz nawiasów klamrowych, więc w pełni skorzystaj z jego funkcji:
Możesz również użyć tej techniki, aby wydrukować każdy numer w osobnej linii z opcjonalnym tekstem, używając
printf
zamiastecho
, na przykład:Edytować
Jak zauważył @kojiro w komentarzu, Mac OS używa bash 3 jako domyślnej powłoki, która nie obsługuje przyrostu wyrażania sekwencji rozwinięcia nawiasu. Musisz zaktualizować do wersji bash 4 lub użyć innej powłoki, która to obsługuje (np. Najnowszy zsh).
źródło
bash -c
gwarantuje , że w grę wchodzą dwie różne powłoki. Czy$SHELL --version
mówi, że to bash 3?bash
tej funkcji została wprowadzona. Nauczyłem się tego sam z komentarza Kojiro. I proszę, nie porównujcie mnie ze SC, naprawdę nie znam wszystkich szczegółów i historii wszystkich pocisków od końca 1970 roku. Jeszcze raz - Jeśli się tego spodziewacie, proszę o głosowanie.Korzystanie z SEQ (1)
Lub po prostu:
źródło
seq 375 5 3500
.Twój fragment for-loop nie działał tak, jak potrzebujesz z dwóch powodów:
(($i += 5))
- tutaj$i
jest rozwinięty do wartościi
. Zatem rozwinięcie będzie podobne((375 += 5))
, co nie ma sensu (próba przypisania liczby literalnej do innej liczby literalnej). Zwykle można to osiągnąć za pomocą((i += 5))
(nie,$
aby rozwinąć zmienną){375..3500}
Zostanie rozszerzony przed pierwszej iteracji pętli. To będzie lista liczb375 376 ... 3499 3500
. Do każdej iteracji pętlii
zostaną przypisane do każdego z tych numerów, jeden po drugim. Zatem na początku każdej iteracjii
zostanie przypisany do następnej wartości na tej liście, licząc w krokach co 1.((i += 5))
Skutecznie nic nie robi - dodaje 5 do i, ale następnie ponownie przypisuje się na początku następna iteracja.Myślę, że najbardziej podoba mi się ta
for (( ; ; ))
odpowiedź, ale oto kilka alternatywnych sposobów na zastanowienie się:Ponieważ mamy do czynienia z wielokrotnościami 5, a
{a..b..i}
rozszerzenie nie jest obsługiwane w wersji bash 3.2.57 (1) (w OS X), możemy zamiast tego zrobić tę nieco tajemniczą rzecz:To pokazuje, jak można użyć bash do stworzenia produktu kartezjańskiego.
Myślę, że generalnie pętla for jest najwygodniejszym sposobem, aby to zrobić, ale jeśli jesteś zainteresowany, możesz użyć programu pętli while (nieco bliżej BASIC):
źródło
38
kasy349
. Na sekundę tylko dwie liczby:0
i5
. Teraz pozwala tworzyć zamówionych par tych wszystkich kombinacjach - można zapisać je jako zestawy:{38,0}
,{38,5}
...{349,5}
, lub po prostu usunąć zbędne symbole{
,,
a}
i dostać ... nowe numery380
...3495
.Chociaż istnieje oczywiście aplikacja do tego (
seq 375 5 3500
), istnieją różne sposoby wykonania tego z wiersza poleceń. Chociaż najszybsza i najprostsza będzie po prostu używaćseq
, oto kilka innych opcji:źródło
$(($i % 5))
można napisać$((i % 5))
.POSIXly:
...lub...
Nie wiem, dlaczego zrobiłbyś to w inny sposób. Z wyjątkiem oczywiście ...
... lub z
dc
:źródło
dc
działa kod. To z pewnością bardziej intrygujące niż używanieseq
.s
aves się[
ciąg]
do górnej częścip
tablicy, a następniel
OAD z powrotem na górę stosu i ex
ecutes go jako makro. W ramach makra wciskamy stos, a następnie wrzucamy5
go, a drugi od góry i+
one, zastępując obie wartości stosu ich sumą, która jestp
zrewidowana id
zastosowana, zanim3500
zostanie wypchnięta na stos, kiedy go pop i dupe, które właśnie stworzyliśmy porównanie>
. Jeśli3500
jest większy, ładujemy i wykonujemy jako makro ciąg przechowywany wp
tablicy (nasze bieżące makro) , lub jeśli nie jest zepsuty.Jeśli utkniesz na Bash 3:
a jeśli wolisz
awk
:Nie wiedziałem o rozszerzaniu nawiasów klamrowych - to naprawdę fajne.
źródło