Autor Tópico: Loop for, problema em fazê-lo funcionar  (Lida 4087 vezes)

Offline Chernobyl_User

  • Usuário Ubuntu
  • *
  • Mensagens: 132
  • ChNPP RBMK-1000
    • Ver perfil
Loop for, problema em fazê-lo funcionar
« Online: 06 de Junho de 2012, 19:29 »
Olá, fiz um script para converter alguns arquivos mp3 para que tenham um tamanho menor, segue o script:

Código: [Selecionar]
#!/bin/bash

#Pergunta pelos arquivos a converter
arquivos=$(zenity --file-selection --multiple --title "Selecione os arquivos que quer converter: " | tr '|' '\n')

#Pergunta pela pasta para por os arquivos convertidos
pasta=$(zenity --file-selection --directory --title "Selecione a pasta onde os arquivos deverão ser salvos: ")

#Conta o total de arquivos a converter
numarq=$(echo "$arquivos" | wc -l)

#Seta o numero base para a contagem
base=1

#Inicia o loop e converte os arquivos
for linha in "$arquivos" ; do

#Obtém o nome do arquivo a ser convertido
nome=$(echo "$linha" | rev | cut -d/ -f1 | rev)

echo "Convertendo arquivo "$base" de "$numarq": "$nome""
case $1 in
f) #Usa o ffmpeg para converter
ffmpeg -i "$linha" -acodec libmp3lame -ac 1 -ab 64k -y -ar 44100 "$pasta"/"$nome" &>> /dev/null
;;
l) #Usa o lame para converter
lame -m m -f -b 64 --cbr "$linha" "$pasta"/"$nome" &>> /dev/null
;;
*) echo "Encoder inválido!"
exit
;;
esac

#Muda o número do arquivo a converter
base=$(($base+1))
done

#Finaliza o programa
echo "Conversão completa!"

#Sai
exit

Ele devia funcionar assim:

1° Pelo terminal eu rodo: bash script.sh (l para o lame ou f para ffmpeg)
2º pede para selecionar os mp3 a converter
3° pede para escolher a pasta de saída
4° converte os arquivos selecionados e manda um output no terminal

O problema é que o laço for não está mandando os arquivos linha por linha para o encoder, ele está mandando tudo de uma vez só:

Código: [Selecionar]
bash Dropbox/Scripts/mp3.sh l
Convertendo arquivo 1 de 2: musicaa 1.mp3 musica 2.mp3
Conversão completa!

Se eu selecionar só um arquivo, tudo funciona. Alguém tem alguma idéia?
Sony Vaio VPCEH30EB/W @ Ubuntu 12.04 + Ubuntu 12.10 + Debian 6.0

Offline irtigor

  • Equipe Ubuntu
  • Usuário Ubuntu
  • *****
  • Mensagens: 4.344
  • Delete, delete, delete!
    • Ver perfil
Re: Loop for, problema em fazê-lo funcionar
« Resposta #1 Online: 06 de Junho de 2012, 21:32 »
É que você tem uma string. Trabalhe com um vetor
Código: [Selecionar]
IFS=\| arquivos=($(zenity --file-selection --multiple --title "Selecione os arquivos que quer converter: "))
for i in "${arquivos[@]}"; do
    #faça alguma coisa o $i
done

Você pode traçar o que o script faz passando a opção "-x".
Código: [Selecionar]
bash -x /caminho/para/o/script.sh

Offline adri3d

  • Usuário Ubuntu
  • *
  • Mensagens: 104
    • Ver perfil
    • http://www.youtube.com/adrianomoreira
Re: Loop for, problema em fazê-lo funcionar
« Resposta #2 Online: 07 de Junho de 2012, 09:23 »
sabe para que serve o caracter & em linhas como essa
Código: [Selecionar]
ffmpeg -i "$linha" -acodec libmp3lame -ac 1 -ab 64k -y -ar 44100 "$pasta"/"$nome" &>> /dev/null
caso não saiba, aprenda vai ser util.

Offline Chernobyl_User

  • Usuário Ubuntu
  • *
  • Mensagens: 132
  • ChNPP RBMK-1000
    • Ver perfil
Re: Loop for, problema em fazê-lo funcionar
« Resposta #3 Online: 07 de Junho de 2012, 23:21 »
Olá irtigor, adaptei sua dica para meu script e a saída do "bash -x" foi:

Código: [Selecionar]
mp3.sh: linha 49: ${$arquivos[@]}: substituição incorreta
Citar
sabe para que serve o caracter & em linhas como essa

Código: [Selecionar]
ffmpeg -i "$linha" -acodec libmp3lame -ac 1 -ab 64k -y -ar 44100 "$pasta"/"$nome" &>> /dev/null
caso não saiba, aprenda vai ser util.

Seria o "&" do "&>> /dev/null? Pelo que eu sei, serve para redirecionar toda e qualquer saída de texto gerada pelo encoder para o lixo. O "&&" é o operador lógico "E".
Sony Vaio VPCEH30EB/W @ Ubuntu 12.04 + Ubuntu 12.10 + Debian 6.0

Offline irtigor

  • Equipe Ubuntu
  • Usuário Ubuntu
  • *****
  • Mensagens: 4.344
  • Delete, delete, delete!
    • Ver perfil
Re: Loop for, problema em fazê-lo funcionar
« Resposta #4 Online: 07 de Junho de 2012, 23:22 »
Mostra o código.

Offline zekkerj

  • Usuário Ubuntu
  • *
  • Mensagens: 19.735
  • Gratidão gera gratidão, lamúria atrai lamúria...
    • Ver perfil
    • Blog do Zekke
Re: Loop for, problema em fazê-lo funcionar
« Resposta #5 Online: 06 de Julho de 2012, 18:11 »
Citar
for linha in "$arquivos" ; do
Acredito que vc colocou a variável entre aspas pra poder lidar com os nomes de arquivos com espaços, correto? Mas assim ele vai tratar todo o conteúdo da variável como uma string só.
Pesquise antes de perguntar, sua dúvida pode já ter sido respondida.
Não respondo dúvidas por MP, coloque sua dúvida no fórum onde ela pode ser pesquisada pelos seus colegas!
Não venha ao fórum apenas para perguntar. Se você sabe a resposta de um problema, porque não ajudar seu colega? ;D

Offline fpissarra

  • Usuário Ubuntu
  • *
  • Mensagens: 246
    • Ver perfil
    • Lost in the e-Jungle
Re: Loop for, problema em fazê-lo funcionar
« Resposta #6 Online: 07 de Julho de 2012, 12:44 »
Olá irtigor, adaptei sua dica para meu script e a saída do "bash -x" foi:

Código: [Selecionar]
mp3.sh: linha 49: ${$arquivos[@]}: substituição incorreta

Talvez isso ajude:

Código: [Selecionar]
OLDIFS=$IFS
IFS=$'|'
arquivos=$(zenity --file-selection --multiple)

for i in $arquivos; do
  // faz algo com $i aqui.
done

IFS=$OLDIFS

No post do irtigor, só faltou um salto de linha depois do ajuste da variável IFS.
« Última modificação: 07 de Julho de 2012, 12:52 por fpissarra »

Offline irtigor

  • Equipe Ubuntu
  • Usuário Ubuntu
  • *****
  • Mensagens: 4.344
  • Delete, delete, delete!
    • Ver perfil
Re: Loop for, problema em fazê-lo funcionar
« Resposta #7 Online: 07 de Julho de 2012, 14:01 »
Não é necessário, do jeito que passei tem que funcionar, por isso pedi pra ver o código, ele errou ao copiar ou coisa do tipo.

Offline fpissarra

  • Usuário Ubuntu
  • *
  • Mensagens: 246
    • Ver perfil
    • Lost in the e-Jungle
Re: Loop for, problema em fazê-lo funcionar
« Resposta #8 Online: 07 de Julho de 2012, 21:00 »
Não é necessário, do jeito que passei tem que funcionar, por isso pedi pra ver o código, ele errou ao copiar ou coisa do tipo.

Irtigor... Isso aqui:

Código: [Selecionar]
IFS=\| arquivos=($(zenity --file-selection --multiple --title "Selecione os arquivos que quer converter: "))
Como está, com certeza não deve funcionar. Não, sem, pelo menos, um ponto-e-virgula depois de '|'.

Offline irtigor

  • Equipe Ubuntu
  • Usuário Ubuntu
  • *****
  • Mensagens: 4.344
  • Delete, delete, delete!
    • Ver perfil
Re: Loop for, problema em fazê-lo funcionar
« Resposta #9 Online: 07 de Julho de 2012, 21:34 »
Funciona e é útil, por exemplo (nada de ponto e vírgula ou nova linha separando a variável)
Código: [Selecionar]
echo $LANG
LANG=en_US.UTF-8 __aplicativo__ &
echo $LANG
Executa __aplicativo__ com a língua inglesa como padrão, como foi executado em subshell, a variável $LANG permanece com o valor anterior no shell atual.

Offline fpissarra

  • Usuário Ubuntu
  • *
  • Mensagens: 246
    • Ver perfil
    • Lost in the e-Jungle
Re: Loop for, problema em fazê-lo funcionar
« Resposta #10 Online: 08 de Julho de 2012, 10:51 »
Funciona e é útil, por exemplo (nada de ponto e vírgula ou nova linha separando a variável)
Código: [Selecionar]
echo $LANG
LANG=en_US.UTF-8 __aplicativo__ &
echo $LANG
Executa __aplicativo__ com a língua inglesa como padrão, como foi executado em subshell, a variável $LANG permanece com o valor anterior no shell atual.

Hummmmm.... interessante!

Offline fpissarra

  • Usuário Ubuntu
  • *
  • Mensagens: 246
    • Ver perfil
    • Lost in the e-Jungle
Re: Loop for, problema em fazê-lo funcionar
« Resposta #11 Online: 08 de Julho de 2012, 13:15 »
Funciona e é útil, por exemplo (nada de ponto e vírgula ou nova linha separando a variável)
Código: [Selecionar]
echo $LANG
LANG=en_US.UTF-8 __aplicativo__ &
echo $LANG
Executa __aplicativo__ com a língua inglesa como padrão, como foi executado em subshell, a variável $LANG permanece com o valor anterior no shell atual.
De fato, é um recurso interessante... mas o IFS só será setado na execução do zenity, não? O loop for continuará separando as strings por espaços, tabs e \n...

Offline irtigor

  • Equipe Ubuntu
  • Usuário Ubuntu
  • *****
  • Mensagens: 4.344
  • Delete, delete, delete!
    • Ver perfil
Re: Loop for, problema em fazê-lo funcionar
« Resposta #12 Online: 08 de Julho de 2012, 16:26 »
Usei um array, tanto faz o IFS depois, mas sim no bash só é alterado pro comando.
Citar
IFS=\| arquivos=($(zenity --file-selection --multiple --title "Selecione os arquivos que quer converter: "))

Offline fpissarra

  • Usuário Ubuntu
  • *
  • Mensagens: 246
    • Ver perfil
    • Lost in the e-Jungle
Re: Loop for, problema em fazê-lo funcionar
« Resposta #13 Online: 09 de Julho de 2012, 09:18 »
Usei um array, tanto faz o IFS depois, mas sim no bash só é alterado pro comando.
Citar
IFS=\| arquivos=($(zenity --file-selection --multiple --title "Selecione os arquivos que quer converter: "))
Ops! É mesmo! Sorry... ficou legal!