Mnożenie i dodawanie Bash

for k in {0..49}; do a=$(($((2*$k))+1)); echo $a; done 

Cześć, potrzebuję uproszczonego wyrażenia dla trzeciego wiersza, może takiego, które tak nie używaj zastępowania poleceń.

Komentarze

  • @Theophrastus: Jak zasugerowano, działa dobrze, ale co jeśli zamiast (()) chciałbym użyć wyrażenia .
  • To jest bash, a nie C, więc usuń wszystkie ; – chyba że napiszesz go w osobnym wierszu.
  • Zobacz też: unix.stackexchange.com/q/40786/117549
  • declare -i a; for k in {0..49}; do a=2*$k+1; echo $a; done
  • Poza tym: $(( ... )) to interpretacja arytmetyczna, a nie podstawianie poleceń.

Odpowiedź

Korzystanie z interpretacji wyrażeń arytmetycznych:

for (( k = 0; k < 50; ++k )); do a=$(( 2*k + 1 )) echo "$a" done 

Używanie przestarzałego narzędzia expr:

for (( k = 0; k < 50; ++k )); do a=$( expr 2 "*" "$k" + 1 ) echo "$a" done 

Używanie bc -l ( -l w rzeczywistości niepotrzebne w tym przypadku, ponieważ nie są używane żadne funkcje matematyczne):

for (( k = 0; k < 50; ++k )); do a=$( bc -l <<<"2*$k + 1" ) echo "$a" done 

Używanie bc -l jako współproces (działa jak rodzaj usługi obliczeniowej w tle¹):

coproc bc -l for (( k = 0; k < 50; ++k )); do printf "2*%d + 1\n" "$k" >&${COPROC[1]} read -u "${COPROC[0]}" a echo "$a" done kill "$COPROC_PID" 

Ten ostatni wygląda (prawdopodobnie) na czystszy w ksh93:

bc -l |& bc_pid="$!" for (( k = 0; k < 50; ++k )); do print -p "2*$k + 1" read -p a print "$a" done kill "$bc_pid" 

¹ To rozwiązało kiedyś problem, w którym musiałem przetworzyć dużą ilość danych wejściowych w pętla. Przetwarzanie wymagało pewnych obliczeń zmiennoprzecinkowych, ale kilkakrotne pojawianie się bc w pętli okazało się wyjątkowo powolne. Tak, mogłem rozwiązać to na wiele innych sposobów, ale nudziłem się …

Odpowiedź

Możesz uprościć:

a=$(($((2*$k))+1)); 

to:

a=$((2*k+1)) 

Odpowiedź

Możesz użyć polecenia let, aby wymusić obliczenia.

let a="2*k+1" 

Zauważ, że w tej strukturze nie „nie potrzebujemy $k; zwykły k wykona zadanie.

Komentarze

  • To się nie powiedzie, jeśli ' plik o nazwie a=2whateverk+1 w bieżącym Gorzej, jeśli istnieje ' plik o nazwie a=2+b[$(reboot)]k+1, który wywołuje polecenie reboot . Najlepiej jest użyć ((...)) tutaj (((a = 2 * k + 1))) lub składni POSIX: a=$((2 * k + 1))
  • Możemy to zacytować; let a="2*k+1" aby to rozwiązać.

Odpowiedź

Rozwinięcie arytmetyczne, którego prawdopodobnie potrzebujesz, to:

a=$(( 1+2*k )) 

W rzeczywistości nie musisz używać zmiennej:

for k in {0..49}; do echo "$(( 1 + 2*k ))" done 

Lub możesz przenieść zmienną zliczającą do for ((…)) loop:

for (( k=0;k<50;k++ )); do a=$(( 1+2*k )) printf "%s\n" "$a" done 

for ((…)) loop

I w takim przypadku rozwinięcie arytmetyczne mogłoby być również przeniesiono do wewnątrz pętli for:

for (( k=0 ; a=1+2*k , k<50 ; k++)); do printf "%s\n" "$a" done 

Lub, aby pobrać wszystkie wartości w tablicy:

for (( k=0 ; a[k]=1+2*k , k<49 ; k++ )); do :; done printf "%s\n" "${a[@]}" 

Brak formuły

Prawdopodobnie najkrótszym sposobem uniknięcia jakichkolwiek interpretacji arytmetycznych jest dwukrotne zwiększenie zmiennej:

for (( k=0,a=1 ; k<50 ; k++,a++,a++ )); do printf "%s\n" "$a" done 

Lub jeszcze prościej, po prostu użyj seq:

seq 1 2 100 

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *