Encontre diretórios que NÃO contêm um arquivo, mas sim outro

2

Eu tenho uma coleção de músicas bastante grande e gostaria de encontrar os diretórios nos quais ainda tenho arquivos compactados (* .rar) não processados. Daí procurando um comando que lista diretórios em que eu não tenho * .flac ou * .mp3, mas YES * .rar presentes. Trabalhando com exemplos encontrados neste post:

Eu tentei:

comm -3 \
    <(find ~/Music/ -iname "*.rar" -not -iname "*.flac" -not -iname "*.mp3" -printf '%h\n' | sort -u) \
    <(find ~/Music/ -maxdepth 5 -mindepth 2 -type d | sort) \
| sed 's/^.*Music\///'

mas não trabalhe.

    
por muixca 02.11.2013 / 16:50

3 respostas

1

O comando a seguir listará todos os diretórios que não contêm .flac ou .mp3 arquivos:

find ~/Music -type d '!' -exec sh -c 'ls -1 "{}"|egrep -iq "^*\.(flac|mp3)$" ' ';' -print

O comando a seguir listará todos os diretórios que contêm .rar arquivos:

find ~/Music -type d -exec sh -c 'ls -1 "{}"|egrep -iq "^*\.rar$"' ';' -print

Agora, unindo esses comandos, o comando a seguir listará todos os diretórios que não contêm .flac ou .mp3 arquivos e que contêm .rar arquivos:

find ~/Music -type d -exec sh -c 'ls -1 "{}"|egrep -iq "^*\.rar$"' ';' \
    '!' -exec sh -c 'ls -1 "{}"|egrep -iq "^*\.(mp3|flac)$" ' ';' -print
    
por Radu Rădeanu 02.11.2013 / 18:20
1

Minha sugestão:

find . -iname '*.rar' -exec bash -c 'cd "${1%/*}"; 
  shopt -s nullglob; files=(*.flac *.mp3); 
  ((${#files[@]} == 0)) && echo ""' _ {} \;

explicação: para cada .rar, pegue seu diretório base, liste * .flac e * .mp3, e se a lista estiver vazia, imprima o nome do arquivo.

    
por enzotib 02.11.2013 / 18:22
0

Há provavelmente uma maneira mais elegante de fazer isso, mas ingenuamente eu gostaria de

  • Obtenha uma lista de diretórios contendo arquivos * .rar (com find e sort -u )
  • Obtenha uma lista de diretórios contendo arquivos * .mp3 e * .flac (também com find )
  • Subtraia essa segunda lista da primeira (usando grep -v )

Então:

find . -iname '*.rar' -printf '%h\n' | sort -u > lista.txt
find . -iregex '.*\(.mp3\|.flac\)' -printf '%h\n' | sort -u > listb.txt
grep -v -f listb.txt lista.txt

Você pode fazer isso sem precisar recorrer a arquivos temporários usando a substituição de processos, como na tentativa da sua pergunta:

grep -v -f <(find . -iregex '.*\(.mp3\|.flac\)' -printf '%h\n' | sort -u) \
<(find . -iname '*.rar' -printf '%h\n' | sort -u)
    
por evilsoup 02.11.2013 / 20:30