fazendo uma matriz de todos os subdiretórios através da saída de um comando

1

Minha idéia é fazer um script que dê todos os subdiretórios (no meu caso ˜ / MÚSICA, mas no mac da minha esposa é diferente - > artista / álbum). Em uma fase posterior, eu gostaria de converter todas as extensões .wav para o mp4 (se ainda não existir).

Mas eu já tenho problemas para obter a saída do comando em uma matriz de string

#!/bin/bash

extFROM=”.wav”;
extTO=”.mp4”;

dir="˜/music";

tree -d

cnt=1;

array;

echo "  part 1";
find $dir -type d | while read line
#ls -d -1 | while read line
do
   array[ $cnt ] = "$line";
   echo "${cnt} "; # :  ${array[ $cnt ] ";
   let cnt++;
done


echo " part 2";
array='awk '{print $1}' <find $dir -type d'
for i in array;
do
   echo "${i} ";
done

Meu pedido de desculpas pelo atraso da minha reação tardia. Parte 1 e parte 2 estão tendo o mesmo objetivo.

Obrigado @Peter Cordes pelas informações sobre como usar linhas de leitura 'while' em vez de 'for-loop'; link e link E, claro, para suas outras reações, é ótimo ter tantas informações úteis.

@Matthew Bohnsack … peça de roteiro agradável e fácil, em vez da minha ideia.

@Saul Ortega , esta é a minha saída: (claro que a árvore)

./test.sh: line 15: array: command not found
part 1
find: ˜/music: No such file or directory
part 2
./test.sh: line 28: find: No such file or directory
array 

Então, tem algo a ver com o meu script, o diretório existe.

    
por kris 18.08.2015 / 17:57

4 respostas

0

Uma versão "find" da resposta de Peter para não obter subdiretórios, mas para fazer todas as conversões, é assim:

convert_if_no_mp4 () {
    wav_file=${1}
    mp4_file="${wav_file%.wav}.mp4"

    if [[ ! -e ${mp4_file} ]]; then
        ffmpeg -i "$wav_file" -c:a libfdk_aac -b:a 96k "$mp4_file"
    fi
}
export -f convert_if_no_mp4
dir=~/MUSIC
find ${dir} -type f -name "*.wav" -exec bash -c 'convert_if_no_mp4 "{}"' \;

Eu suspeito que isso é o que você está procurando (na verdade, fazendo a conversão), mas se você realmente quer operar em todos os subdiretórios por algum motivo, você pode começar com algo assim:

do_stuff_with_subdir () {
    echo "doing something with \"${1}\""
}
export -f do_stuff_with_subdir
dir=~/MUSIC
find ${dir} -type d -exec bash -c 'do_stuff_with_subdir "{}"' \;
    
por 18.08.2015 / 22:00
3

Consulte o link e o link como ler linhas que potencialmente contêm espaços e outros caracteres especiais.

Há um monte de coisas erradas sobre como você está lidando com texto em seu script. Está sujeito à divisão de palavras em muitos casos que você não deseja. Veja a FAQ do Wooledge para mais detalhes.

Os arquivos de áudio geralmente têm nomes com espaços, por isso isso será um problema para você.

Uma maneira de fazer isso seria usar o recurso extglob do Bash para evitar a necessidade de analisar find output. ( find -exec ... {} + seria outro caminho).

shopt -s extglob
for wav in **/*.wav; do
    mp4="${wav%.wav}.mp4"  # strip off the .wav suffix, tack on .mp4
    if ! [[ -e "$mp4" ]]; then
        ffmpeg -i "$wav" -c:a libfdk_aac -b:a 96k "$mp4"
    fi
done

Note que os outros codificadores AAC do ffmpeg ainda não são tão bons quanto o libfdk .

    
por 18.08.2015 / 19:11
0

para colocar toda a saída de um comando em uma matriz BASH, basta fazer isso:

 array=( $( command ) )

Poupe toda a parte while read . Tenha cuidado com os caracteres especiais nos nomes.

    
por 18.08.2015 / 18:59
0

Verifique o código a seguir para sua primeira parte:

#!/bin/bash   
extFROM=”.wav”  
extTO=”.mp4”  
dir="˜/music"  
tree -d  
cnt=1  
array  
echo "  part 1"  

find $dir -type d | while read line  
do  
   array[ $cnt ]="$line"  
   echo ""${cnt}" :  ${array[ $cnt ]}"  
   let cnt++;  
done

Para a segunda parte, você pode dar mais algumas informações, como o que deseja fazer depois de obter todos os subdiretórios.

    
por 18.08.2015 / 19:31