Estoy escribiendo un script de shell para Linux, usando Bash, para traducir cualquier archivo de video a un MP4. Para eso, estoy usando avconvcon libvorbispara 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 avconvlí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 libvorbisusa. 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
-gesignifica mayor o igual a (y así sucesivamente). El-aes 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[$REPLYy 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 bashbajoCompound Commands.foo='a'; [[ "$foo" -lt 32 ]] && echo yesSimplemente podrías decir:
Citando del manual :
fuente
((? Traté de usarlos rápidamente y parece funcionar,if [ ] ; thenpero no sabía que existía.if [ condition ]; then foo; fies 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 && cmdNo es exactamente lo mismo queif cmd; then ...una vez que necesita unaelseparte, 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:
-gtoperador 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