Estou escrevendo um shell script para Linux, usando o Bash, para converter qualquer arquivo de vídeo em um MP4. Para isso, estou usando avconv
com libvorbis
áudio.
Dentro do meu script, tenho uma pergunta para o usuário:
read -p "- Audio Quality [scale from -2 to 10] ? "
if [ -n "$REPLY" ] ; then
ABITRATE="-aq $REPLY"
fi
Minha seqüência de caracteres "ABITRATE" vai para a avconv
linha de comando final .
Mas eu gostaria de dar ao usuário a oportunidade de responder a essa pergunta com um valor em Kb (Kilobit) e traduzi-la na escala libvorbis
usada. A "escala de -2 a 10" é a seguinte:
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
Gostaria de saber como verificar se meu $ REPLY está em um intervalo de número. Por exemplo, eu gostaria que meu script fizesse algo assim:
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
Isso é possível (estou disposto a dizer 'sim, claro, não deve ser difícil', mas não conheço a sintaxe a ser usada)?
bash
shell-script
arithmetic
MrVaykadji
fonte
fonte
Respostas:
O
[
comando / shell interno possui testes de comparação, para que você possa fazeronde
-ge
significa maior ou igual a (e assim por diante). O-a
é lógico "e". O[
comando é apenas um comando, não uma sintaxe especial (na verdade, é o mesmo quetest
: check-outman test
); portanto, ele precisa do espaço a seguir. Se você escrever,[$REPLY
ele tentará encontrar um comando chamado[$REPLY
e executá-lo, o que não funcionará. O mesmo vale para o fechamento]
.Editar: para testar se o número é inteiro (se isso pode acontecer no seu código), primeiro faça o teste
É claro que todas essas expressões de colchete retornam 0 (verdadeiro) ou 1 (falso) e podem ser combinadas. Além de colocar tudo no mesmo suporte, você também pode
ou algo semelhante.
fonte
>=
?[
colchetes tradicionais , que funcionam como visto emman test
. Estes são tradicionais e à prova de idiotas. Então, você tem muitos bash builtins. Você tem[[
quais são semelhantes, mas não exatamente iguais, pois este não expande nomes de caminho (lá, <=> comparações médias de strings e comparações inteiras são as mesmas que em[
). Ambos também têm muitos testes para existência de arquivos, permissões e assim por diante. Então você usa o single(
e o double((
na resposta do @ devnull. Confiraman bash
emCompound Commands
.foo='a'; [[ "$foo" -lt 32 ]] && echo yes
Você poderia simplesmente dizer:
Citando o manual :
fonte
((
? Tentei usá-los rapidamente e parece que funcionava,if [ ] ; then
mas não sabia que existia.if [ condition ]; then foo; fi
é equivalente a dizercondition && foo
.a=08; (( a > 1 ))
irá erro desde 08 é considerado octal. você também pode forçar decimal com10#$REPLY
.cmd && cmd
não é exatamente o mesmo queif cmd; then ...
Depois que você precisar de umaelse
peça, encadeará a lógica&&
e||
poderá causar erros sutis.Você poderia fazer algo assim:
fonte
Primeiro, teste se a entrada é numérica. Por exemplo, usando o operador de correspondência de expressão regular de expressões condicionais do bash :
Para testar intervalos numéricos, você tem duas possibilidades:
-gt
operador de expressões condicionais internas[ … ]
ou[[ … ]]
(cuidado para que os operadores<
e>
façam comparação de cadeias, não comparação de valores numéricos, isso[[ 10 < 9 ]]
é verdade);((…))
.Portanto:
(Você pode usar diferentes regras de aproximação, não sei se as que escolhi são as melhores aqui.)
fonte
Para detectar corretamente se uma string é um número (decimal), primeiro precisamos definir o que é um número inteiro decimal. Uma definição simples e bastante completa é:
E estas etapas são necessárias:
Apenas uma regex fará a maior parte disso:
O código para processar vários números é:
Qual será impresso:
Quando o número estiver limpo e claro, o único teste que falta é limitar o intervalo de valores. Este simples par de linhas fará isso:
fonte