Piszę skrypt powłoki dla systemu Linux, używając Bash, aby przetłumaczyć dowolny plik wideo na MP4. Do tego używam avconv
z libvorbis
dźwiękiem.
Wewnątrz mojego skryptu mam pytanie do użytkownika:
read -p "- Audio Quality [scale from -2 to 10] ? "
if [ -n "$REPLY" ] ; then
ABITRATE="-aq $REPLY"
fi
Mój ciąg „ABITRATE” przechodzi do ostatniego avconv
wiersza polecenia.
Chciałbym jednak dać użytkownikowi możliwość odpowiedzi na to pytanie wartością Kb (Kilobit) i przetłumaczenia go na libvorbis
używaną skalę . „Skala od -2 do 10” jest następująca:
Quality Kbit/s Normalization
-----------------------------
-2 ~32 y
-1 ~48 y
0 ~64 y
1 ~80 y
2 ~96 y
3 ~112 y
4 ~128 n
5 ~160 n
6 ~192 n
7 ~224 n
8 ~256 n
9 ~320 n
10 ~500 n
Chciałbym wiedzieć, jak sprawdzić, czy mój $ REPLY mieści się w zakresie liczby. Na przykład chciałbym, aby mój skrypt zrobił coś takiego:
if [ $REPLY is a number between 1 and 32 ] ; then
REPLY="-2"
elif [ $REPLY is a number between 33 and 48 ] ; then
REPLY="-1"
fi
Czy to możliwe (jestem gotów powiedzieć „tak, oczywiście, nie powinno być trudne”, ale nie znam składni)?
bash
shell-script
arithmetic
MrVaykadji
źródło
źródło
Odpowiedzi:
[
Wbudowane polecenie / powłoka ma testów porównawczych, więc można po prostu zrobićgdzie
-ge
oznacza większą-lub-równą (i tak dalej). Jest-a
to logiczne „i”.[
Komenda jest tylko komenda, nie specjalnej składni (to faktycznie takie same, jaktest
: sprawdzeniuman test
), więc potrzebuje miejsca po niej. Jeśli napiszesz[$REPLY
, spróbuje znaleźć polecenie o nazwie[$REPLY
i wykonać je, co nie będzie działać. To samo dotyczy zamknięcia]
.Edycja: aby sprawdzić, czy liczba jest liczbą całkowitą (jeśli może się tak zdarzyć w kodzie), najpierw wykonaj test
Oczywiście wszystkie te wyrażenia w nawiasach zwracają 0 (prawda) lub 1 (fałsz) i można je łączyć. Nie tylko możesz umieścić wszystko w tym samym przedziale, możesz także
lub coś podobnego.
źródło
>=
?[
nawiasy, które działają jak widać wman test
. Są to tradycyjne i głupie. Następnie masz wiele wbudowanych wersji bash. Masz[[
podobne, ale niezupełnie takie same, ponieważ ten nie rozwija nazw ścieżek (tam <=> średnie porównania ciągów, a porównania liczb całkowitych są takie same jak w[
). Oba mają również wiele testów na istnienie pliku, uprawnienia i tak dalej. Następnie masz jedno(
i podwójne((
użyte w odpowiedzi @ devnull. Sprawdźman bash
podCompound Commands
.foo='a'; [[ "$foo" -lt 32 ]] && echo yes
Możesz po prostu powiedzieć:
Cytowanie z instrukcji :
źródło
((
? Próbowałem użyć ich natychmiast i wydaje się, że działa tak,if [ ] ; then
ale nie wiedziałem, że istnieje.if [ condition ]; then foo; fi
jest równoważne powiedzeniucondition && foo
.a=08; (( a > 1 ))
popełni błąd, ponieważ 08 uważa się za ósemkowy. możesz również wymusić dziesiętne za pomocą10#$REPLY
.cmd && cmd
to nie to samo, coif cmd; then ...
raz potrzebnaelse
część, logiczne tworzenie łańcuchów&&
i||
może powodować subtelne błędy.Możesz zrobić coś takiego:
źródło
Najpierw sprawdź, czy dane wejściowe są numeryczne. Na przykład za pomocą operatora dopasowania wyrażeń regularnych wyrażeń warunkowych bash :
Aby przetestować zakresy liczbowe, masz dwie możliwości:
-gt
operator wyrażeń warunkowych wewnątrz[ … ]
lub[[ … ]]
(uwaga, że<
i>
operatorzy zrobić porównanie ciąg, nie numeryczny porównania wartość, więc[[ 10 < 9 ]]
jest true);((…))
.A zatem:
(Być może chcesz zastosować inne reguły zbliżenia, nie wiem, czy te, które wybrałem, są tutaj najlepsze).
źródło
Aby poprawnie wykryć, czy łańcuch jest liczbą (dziesiętną), najpierw musimy zdefiniować, jaka jest dziesiętna liczba całkowita. Prosta, a mimo to kompletna definicja to:
A te kroki są potrzebne:
Tylko jedno wyrażenie regularne zrobi większość tego:
Kod przetwarzający kilka liczb to:
Który wydrukuje:
Gdy liczba jest już czysta i wyraźna, jedynym brakującym testem jest ograniczenie zakresu wartości. Ta prosta para wierszy zrobi to:
źródło