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
  • 1
  • 2
  • You could use `ls -R ~/Music | grep .rar` to find files with a filename containing '.rar' - this will just find and list the .rar files. This may work better than the `find` command. – Wilf Nov 02 '13 at 16:01
  • See also https://unix.stackexchange.com/questions/381373/search-for-directories-containing-one-file-and-missing-another – tripleee Jul 10 '18 at 06:52

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
  • 166,822
  • 48
  • 327
  • 400
  • Thanks for the elaborate explanation. Neat script! Discovered some interesting hidden corners in my collection... – muixca Nov 03 '13 at 10:47
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
  • 92,255
  • 11
  • 164
  • 178
  • THANK YOU TO ALL!! I appreciate your time and knowledge. All work like a charm. Respectfully m~ – muixca Nov 03 '13 at 10:05
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,435
  • 1
  • 19
  • 26