Search code examples
bashloopsscriptingcygwin

Get directories without specific filetype cygwin/bash


I am trying to organise my music collection's album art, for XBMC etc. and my own personal OCD based reasons. To do this, I want to loop through each folder in my music collection, (there are also files in music hence $(find . -type d). I check each folder for the existence of a jpeg. If it exists, it is copied to be called cover.jpg. If no jpeg is found, the name of the folder should be added to a list, which I'll then search google for myself. The code I'm using is below.

#!/bin/bash

IFS=$'\n'

touch missing

cd /cygdrive/d/music

for i in $(find . -type d)
    do cd $i
    if [ -e '*.jpg' ]
    then
        for j in *.jpg
            do cp $j 'cover.jpg'
        done
    else
        cd ..
        $i >> missing
    fi
done

The Problems

  1. cd $i always fails, as the directory does not exist.
  2. $i >> missing always fails, with a permission is denied error, however ls -l missing gives -rwxrwxrwx+ 1 Username None 0 Sep 13 16:45 missing

Update:

After trying several iterations to get the script to work, I had to give up and simply use this Album Art Downloader, which in hindsight was the obvious thing to do. I'm marking the answer with a revised script as accepted as it got me closer to the solution I know is out there, somewhere.


Solution

  • 1) cd $i always fails, as the directory does not exist.

    since the result of find . -type -d is relative to your where you initial working directory, you'll need to cd back to the base directory before doing the nextcd $1. A quick way to return to the previous directory is cd -.

    2) $i >> missing always fails, with a permission is denied error,

    Two problems here. First of all, by doing $i >> missing you're actually trying to execute $i as a command. If you want the filename appended to the file, you'll need to use echo $i >> missing.

    Secondly, you created missing in your initial working directory, and so you're actually dealing with a different missing file once you've cd'ed somewhere else. To refer to the same file, use an absolute path.

    Try this: (I tried to keep the script as close to what you have as possible and commented on lines that I changed. I've also quoted all paths to better handle filenames with spaces)

    #!/bin/bash
    IFS=$'\n'
    MISSING="$(pwd)/missing"  # store absolute path
    > "$MISSING". # create new or empty existing
    
    cd /cygdrive/d/music
    
    for i in $(find . -type d)
        do 
        cd "$i"
        if [ -e *.jpg ]  # wildcard not expanded if quoted
        then
            for j in *.jpg
                do cp "$j" 'cover.jpg'
            done
        else
            echo "$i" >> "$MISSING"  # use $MISSING
        fi
        cd -  # go back to previous directory
    done
    

    p.s. Just in case you haven't noticed, do be aware that if you have more than one *.jpg file in a directory, your script will essentially repeatedly overwrite cover.jpg with the last one ending up as the actual version. Also, you're likely to see the error "cp: 'cover.jpg' and 'cover.jpg' are the same file" if you have more than one jpg file and when cover.jpg already exists.