Próbowałem inkrementować zmienną numeryczną przy użyciu obu var=$var+1i var=($var+1)bez powodzenia. Zmienna jest liczbą, choć wydaje się, że bash odczytuje ją jako ciąg znaków.
Wersja Bash 4.2.45 (1) -release (x86_64-pc-linux-gnu) na Ubuntu 13.10.
Zdecydowanie lepiej niż zaakceptowana odpowiedź. Na zaledwie 10% tyle miejsca udało ci się podać wystarczającą liczbę przykładów (jeden to dużo - dziewięć to przesada do tego stopnia, że się popisujesz) i dostarczyłeś nam wystarczających informacji, aby wiedzieć, że ((...))jest to klucz do korzystania z arytmetyki w bash. Nie zdawałem sobie sprawy, że patrząc tylko na przyjętą odpowiedź - pomyślałem, że istnieje dziwny zestaw zasad dotyczących kolejności operacji lub coś, co prowadzi do całego nawiasu w zaakceptowanej odpowiedzi.
Dzięki odpowiedzi Radu Rădeanu, która zapewnia następujące sposoby zwiększania zmiennej w bash:
var=$((var+1))((var=var+1))((var+=1))((var++))
let "var=var+1"
let "var+=1"
let "var++"
Są też inne sposoby. Na przykład spójrz na inne odpowiedzi na to pytanie.
let var++
var=$((var++))((++var)){
declare -i var
var=var+1
var+=1}{
i=0
i=$(expr $i +1)}
Posiadanie tak wielu opcji prowadzi do tych dwóch pytań:
Czy jest między nimi różnica w wydajności?
Jeśli tak, to które, które działa najlepiej?
Kod przyrostowego testu wydajności:
#!/bin/bash# To focus exclusively on the performance of each type of increment# statement, we should exclude bash performing while loops from the# performance measure. So, let's time individual scripts that# increment $i in their own unique way.# Declare i as an integer for tests 12 and 13.
echo > t12 'declare -i i; i=i+1'
echo > t13 'declare -i i; i+=1'# Set i for test 14.
echo > t14 'i=0; i=$(expr $i + 1)'
x=100000while((x--));do
echo >> t0 'i=$((i+1))'
echo >> t1 'i=$((i++))'
echo >> t2 '((i=i+1))'
echo >> t3 '((i+=1))'
echo >> t4 '((i++))'
echo >> t5 '((++i))'
echo >> t6 'let "i=i+1"'
echo >> t7 'let "i+=1"'
echo >> t8 'let "i++"'
echo >> t9 'let i=i+1'
echo >> t10 'let i+=1'
echo >> t11 'let i++'
echo >> t12 'i=i+1'
echo >> t13 'i+=1'
echo >> t14 'i=$(expr $i + 1)'donefor script in t0 t1 t2 t3 t4 t5 t6 t7 t8 t9 t10 t11 t12 t13 t14;do
line1="$(head -1 "$script")"
printf "%-24s""$line1"{ time bash "$script";}|& grep user# Since stderr is being piped to grep above, this will confirm# there are no errors from running the command:eval"$line1"
rm "$script"done
Wyniki:
i=$((i+1)) user 0m0.992s
i=$((i++)) user 0m0.964s((i=i+1)) user 0m0.760s((i+=1)) user 0m0.700s((i++)) user 0m0.644s((++i)) user 0m0.556s
let "i=i+1" user 0m1.116s
let "i+=1" user 0m1.100s
let "i++" user 0m1.008s
let i=i+1 user 0m0.952s
let i+=1 user 0m1.040s
let i++ user 0m0.820s
declare -i i; i=i+1 user 0m0.528s
declare -i i; i+=1 user 0m0.492s
i=0; i=$(expr $i +1) user 0m5.464s
Wniosek:
Wydaje się, że bash działa najszybciej, i+=1gdy $ijest zadeklarowany jako liczba całkowita. letinstrukcje wydają się szczególnie wolne i exprsą zdecydowanie najwolniejsze, ponieważ nie są wbudowane.
Podczas gdy odpowiedzi Radu i komentarze są wyczerpujące i bardzo pomocne, są one specyficzne dla bash. Wiem, że konkretnie spytałeś o bash, ale pomyślałem, że się do niego odezwę, ponieważ znalazłem to pytanie, gdy szukałem tego samego, używając sh w busyboxie pod uCLinux. To przenośne poza bash.
We wszystkich odpowiedziach brakuje jednej metody - bc
$ VAR=7
$ bc <<<"$VAR+2"9
$ echo $VAR7
$ VAR=$( bc <<<"$VAR+1")
$ echo $VAR8
bcjest określony przez standard POSIX , więc powinien być obecny we wszystkich wersjach systemów zgodnych z Ubuntu i POSIX. <<<Przekierowanie może być zmienione, aby echo "$VAR" | bcdo przenoszenia, ale skoro pytanie pyta o bash- to OK, aby po prostu używać <<<.
Kod zwrotny 1problem występuje dla wszystkich wariantów (domyślne let, (())itp). To często powoduje problemy, np set -o errexit. W używanych skryptach . Oto, czego używam, aby zapobiec kodowi błędu 1wyrażeń matematycznych, które oceniają 0;
math(){(("$@"))|| true;}
math a =10, b =10
math a++, b+=2
math c = a + b
math mod = c %20
echo $a $b $c $mod#11 12 23 3
To musi być najgorszy sposób na wykonanie tak prostego zadania, ale chyba po prostu chciałem to udokumentować dla zabawy (kompletne przeciwieństwo kodu golfa).
Używamy plików cookie i innych technologii śledzenia w celu poprawy komfortu przeglądania naszej witryny, aby wyświetlać spersonalizowane treści i ukierunkowane reklamy, analizować ruch w naszej witrynie, i zrozumieć, skąd pochodzą nasi goście.
Kontynuując, wyrażasz zgodę na korzystanie z plików cookie i innych technologii śledzenia oraz potwierdzasz, że masz co najmniej 16 lat lub zgodę rodzica lub opiekuna.
((++var))
lub((var=var+1))
lub((var+=1))
.