2

I have quite a large music collection and would like to find the directories in which I still have compressed files (*.rar) unprocessed. Hence looking for a command that lists directories in which i do NOT have *.flac or *.mp3 but YES *.rar present. Working off found examples in this post:

I tried:

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\///'

but don' work.

muixca
  • 21

3 Answers3

1

The following command will list all directories that don't contain .flac or .mp3 files:

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

And the following command will list all directories that contain .rar files:

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

Now, joining these commands, the following command will list all directories that don't contain .flac or .mp3 files and that contain .rar files:

find ~/Music -type d -exec sh -c 'ls -1 "{}"|egrep -iq "^*\.rar$"' ';' \
    '!' -exec sh -c 'ls -1 "{}"|egrep -iq "^*\.(mp3|flac)$" ' ';' -print
Radu Rădeanu
  • 174,089
  • 51
  • 332
  • 407
1

My suggestion:

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

explanation: for every .rar, take its base dir, list *.flac and *.mp3, and if the list is empty print the filename.

enzotib
  • 96,093
0

There is probably a more elegant way of doing this, but naively I would want to

  • Get a list of directories containing *.rar files (with find and sort -u)
  • Get a list of directories containing *.mp3 and *.flac files (also with find)
  • Subtract this second list from the first (using grep -v)

So:

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

You can do it without having to resort to temporary files by using process substitution, as in the attempt in your question:

grep -v -f <(find . -iregex '.*\(.mp3\|.flac\)' -printf '%h\n' | sort -u) \
<(find . -iname '*.rar' -printf '%h\n' | sort -u)
evilsoup
  • 4,625