$ find
.
./folder3
./folder3/quux.txt
./folder1
./folder1/test.mp3
./folder1/test.txt
./folder1/test.wma
./folder2
./folder2/bar.txt
./folder2/foo.txt
./folder2/test.ogg
Exemplo é executado:
$ ./findaudio.sh /tmp/findaudio 1
/tmp/findaudio/folder2/test.ogg
$ ./findaudio.sh /tmp/findaudio 2
/tmp/findaudio/folder1/test.mp3
/tmp/findaudio/folder1/test.wma
# The first parameter defaults to the current directory and
# the second parameter defaults to 1 so this works as well:
$ ./findaudio.sh
./folder2/test.ogg
E aqui o código:
#!/bin/bash
shopt -s nullglob
find "${1:-.}" -type d | while read dir; do
files=( "${dir}"/*.{mp4,mp3,ogg,flac,wma,m4a} )
IFS=$'\n'
(( ${#files[@]} == ${2:-1} )) && echo "${files[*]}"
done
Ele itera sobre todos os subdiretórios do diretório especificado e usa globbing para ler todos os nomes de arquivos de áudio do subdiretório atual no array files
. Se o tamanho da matriz corresponder ao valor desejado, basta imprimir os nomes dos arquivos separados por uma nova linha.
EDIT: Esta é a minha abordagem anterior baseada no pressuposto de que você queria imprimir as pastas, não os nomes de arquivos em questão. Vou deixar aqui para referência futura.
$ find . \( -name '*.ogg' -o -name '*.wma' -o -name '*.mp3' \) -printf "%h\n" | uniq -u
./folder2
O que isto faz é encontrar todos os arquivos com as extensões de áudio listadas e imprimir apenas seus componentes de diretório em vez do caminho completo. Isso fornece uma lista de pastas pai para todos os arquivos de áudio. O uniq
ignora as linhas não exclusivas que devem fornecer o resultado desejado, ou seja, apenas as pastas de impressão que contêm exatamente um arquivo de áudio.
Em teoria, isso também deve ser um pouco mais rápido do que sua tentativa anterior.
Você pode melhorar isso para satisfazer seu primeiro ponto, contando as linhas duplicadas e imprimindo apenas as pastas que correspondem à sua contagem solicitada. Uma solução ingênua seria:
$ find . \( -name '*.ogg' -o -name '*.wma' -o -name '*.mp3' \) -printf "%h\n" | uniq -c | awk -v count=1 '$1==count'
1 ./folder2
$ find . \( -name '*.ogg' -o -name '*.wma' -o -name '*.mp3' \) -printf "%h\n" | uniq -c | awk -v count=2 '$1==count'
2 ./folder1
embora seja melhor fundir o uniq
-part e o lado direito do canal em uma única linha awk
.