Estoy escribiendo un script de shell para Linux, usando Bash, para traducir cualquier archivo de video a un MP4. Para eso, estoy usando avconv
con libvorbis
para audio.
Dentro de mi script, tengo una pregunta para el usuario:
read -p "- Audio Quality [scale from -2 to 10] ? "
if [ -n "$REPLY" ] ; then
ABITRATE="-aq $REPLY"
fi
Mi cadena "ABITRATE" va a la avconv
línea de comando final .
Pero me gustaría darle al usuario la oportunidad de responder esa pregunta con un valor en Kb (Kilobit) y traducirla a la escala que libvorbis
usa. La "escala de -2 a 10" es esta:
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
Me gustaría saber cómo verificar si mi $ REPLY está en un rango de números. Por ejemplo, me gustaría que mi script haga algo como esto:
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
¿Es esto posible (estoy dispuesto a decir 'sí, por supuesto, no debería ser difícil' pero no sé la sintaxis que debo usar)?
bash
shell-script
arithmetic
MrVaykadji
fuente
fuente
Respuestas:
El
[
comando / shell incorporado tiene pruebas de comparación, por lo que puede hacerdonde
-ge
significa mayor o igual a (y así sucesivamente). El-a
es lógico "y". El[
comando es solo un comando, no una sintaxis especial (en realidad es lo mismo quetest
: check outman test
), por lo que NECESITA el espacio posterior. Si lo escribe[$REPLY
, intentará encontrar un comando llamado[$REPLY
y ejecutarlo, lo que no funcionará. Lo mismo vale para el cierre]
.Editar: para probar si el número es entero (si eso puede suceder en su código), primero haga la prueba
Por supuesto, todas estas expresiones de paréntesis devuelven 0 (verdadero) o 1 (falso) y se pueden combinar. No solo puedes poner todo en el mismo soporte, también puedes hacer
o algo similar.
fuente
>=
?[
soportes tradicionales , que funcionan como se ve enman test
. Estos son tradicionales y a prueba de tontos. Entonces, tienes muchas bash builtins. Tiene[[
cuáles son similares, pero no exactamente lo mismo, ya que este no expande los nombres de ruta (allí, <=> las comparaciones de cadenas medias y las comparaciones de enteros son las mismas que en[
). Ambos también tienen muchas pruebas de existencia de archivos, permisos, etc. Entonces tienes simple(
y doble((
usado en la respuesta de @ devnull. Salidaman bash
bajoCompound Commands
.foo='a'; [[ "$foo" -lt 32 ]] && echo yes
Simplemente podrías decir:
Citando del manual :
fuente
((
? Traté de usarlos rápidamente y parece funcionar,if [ ] ; then
pero no sabía que existía.if [ condition ]; then foo; fi
es equivalente a decircondition && foo
.a=08; (( a > 1 ))
se producirá un error ya que 08 se considera octal. También puedes forzar el decimal con10#$REPLY
.cmd && cmd
No es exactamente lo mismo queif cmd; then ...
una vez que necesita unaelse
parte, el encadenamiento lógico&&
y||
puede causar errores sutiles.Podrías hacer algo como esto:
fuente
Primero, pruebe si la entrada es numérica. Por ejemplo, utilizando el operador de coincidencia de expresiones regulares de expresiones condicionales bash :
Para probar rangos numéricos, tiene dos posibilidades:
-gt
operador de expresiones condicionales dentro de[ … ]
o[[ … ]]
(tenga en cuenta que los operadores<
y>
hacen una comparación de cadenas, no una comparación de valores numéricos, por lo que[[ 10 < 9 ]]
es cierto);((…))
.Así:
(Es posible que desee utilizar diferentes reglas de aproximación, no sé si las que elegí son las mejores aquí).
fuente
Para detectar correctamente si una cadena es un número (decimal), primero debemos definir qué es un número entero decimal. Una definición simple pero bastante completa es:
Y estos pasos son necesarios:
Solo una expresión regular hará la mayor parte de eso:
El código para procesar varios números es:
Que imprimirá:
Una vez que el número está limpio y claro, la única prueba que falta es limitar el rango de valores. Este simple par de líneas hará eso:
fuente