J'écris un script shell pour Linux, en utilisant Bash, pour traduire n'importe quel fichier vidéo en MP4. Pour cela, j'utilise avconv
avec libvorbis
pour l'audio.
Dans mon script, j'ai une question pour l'utilisateur:
read -p "- Audio Quality [scale from -2 to 10] ? "
if [ -n "$REPLY" ] ; then
ABITRATE="-aq $REPLY"
fi
Ma chaîne "ABITRATE" va dans la avconv
ligne de commande finale .
Mais je voudrais donner à l'utilisateur la possibilité de répondre à cette question avec une valeur en Kb (Kilobit), et de la traduire dans l'échelle qui libvorbis
utilise. "L'échelle de -2 à 10" est la suivante:
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
Je voudrais savoir comment vérifier si ma $ REPLY est dans une plage de nombres. Par exemple, je voudrais que mon script fasse quelque chose comme ceci:
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
Est-ce possible (je suis prêt à dire «oui bien sûr, ça ne devrait pas être difficile» mais je ne connais pas la syntaxe à utiliser)?
la source
Réponses:
La
[
commande / shell intégré a des tests de comparaison, vous pouvez donc simplement faireoù
-ge
signifie supérieur ou égal à (et ainsi de suite). Le-a
est logique "et". La[
commande est juste une commande, pas une syntaxe spéciale (c'est en fait la même chose quetest
: vérifierman test
), donc elle A BESOIN de l'espace après. Si vous l'écrivez,[$REPLY
il essaiera de trouver une commande nommée[$REPLY
et l'exécutera, ce qui ne fonctionnera pas. Il en va de même pour la fermeture]
.Edit: pour tester si le nombre est entier (si cela peut arriver dans votre code), faites d'abord le test
Bien sûr, toutes ces expressions de parenthèses renvoient 0 (vrai) ou 1 (faux) et peuvent être combinées. Non seulement vous pouvez tout mettre dans le même support, vous pouvez également le faire
ou quelque chose de similaire.
la source
>=
?[
supports traditionnels , qui fonctionnent comme indiqué dansman test
. Ce sont traditionnels et infaillibles. Ensuite, vous avez beaucoup de commandes bash. Vous en avez[[
qui sont similaires, mais pas exactement les mêmes, car celui-ci ne développe pas les noms de chemin (là, <=> les comparaisons de chaînes moyennes et les comparaisons d'entiers sont les mêmes que dans[
). Les deux ont également beaucoup de tests pour l'existence de fichiers, les autorisations, etc. Ensuite, vous avez utilisé le simple(
et le double((
dans la réponse de @ devnull. Découvrezman bash
sousCompound Commands
.foo='a'; [[ "$foo" -lt 32 ]] && echo yes
Vous pourriez simplement dire:
Citant du manuel :
la source
((
? J'ai essayé de les utiliser à l'invite et cela semble fonctionner commeif [ ] ; then
mais je ne savais pas que cela existait.if [ condition ]; then foo; fi
est équivalent à direcondition && foo
.a=08; (( a > 1 ))
erreur car 08 est considéré comme octal. vous pouvez également forcer la décimale avec10#$REPLY
.cmd && cmd
n'est pas tout à fait la même chose qu'uneif cmd; then ...
fois que vous avez besoin d'uneelse
pièce, l'enchaînement logique&&
et||
peut provoquer des bugs subtils.Vous pouvez faire quelque chose comme ça:
la source
Tout d'abord, testez si l'entrée est numérique. Par exemple, en utilisant l'opérateur de correspondance d'expressions régulières d'expressions conditionnelles bash :
Pour tester des plages numériques, vous avez deux possibilités:
-gt
opérateur d' expressions conditionnelles à l' intérieur de[ … ]
ou[[ … ]]
(attention, les opérateurs<
et>
font une comparaison de chaînes, et non une comparaison de valeurs numériques,[[ 10 < 9 ]]
c'est vrai);((…))
.Ainsi:
(Vous voudrez peut-être utiliser différentes règles d'approximation, je ne sais pas si celles que j'ai choisies sont les meilleures ici.)
la source
Pour détecter correctement si une chaîne est un nombre (décimal), nous devons d'abord définir ce qu'est un nombre entier décimal. Une définition simple et pourtant assez complète est:
Et ces étapes sont nécessaires:
Un seul regex fera la plupart de cela:
Le code pour traiter plusieurs nombres est:
Qui imprimera:
Une fois que le nombre est propre et clair, le seul test manquant est de limiter la plage de valeurs. Ce simple couple de lignes fera cela:
la source