0

I'm currently trying to write a little script to convert all the flac files to mp3 files. However, I ran into a bit of a problem when trying to set up recursion down into all my music folders - the script kept looping into the current directory (.)

Here's what I currently have:

#!/bin/bash

#---
# flacToMp3: Converts FLAC files in my originalFLAC folder into mp3 files
#            and places them in an identical folder structure in my Music
#            folder.
#---

function enterDIR {
    for DIR in "$(find . -maxdepth 1 -type d)"; do #recurse into every directory below top-level directory
        if [ "$DIR" == "." ]; then  #avoid current directory infinite loop
            continue
        fi
        cd "$DIR/"
        enterDIR
    done

    createDirectory
    convertFLAC
}

function createDirectory {
    #recreate directory structure in Music folder
    curDir="$pwd"
    newDir=${curDir/originalFLAC/Music}
    mkdir -p $newDir
}

function convertFLAC {
    #convert each flac file in current directory into an mp3 file
    for FILE in "$(find . -maxdepth 1 -type f)"; do #loop through all regular (non-directory) files in current directory
        if [ "${FILE: -5}" == ".flac" ]; then #if FILE has extension .flac
            ffmpeg -i "$FILE" -ab 320k -map_metadata 0 "${FILE%.*}.mp3"; #convert to .mp3
            mv -u "${FILE%.*}.mp3" $newDir
        else #copy all other files to new directory as-is
            cp -ur "$FILE" $newDir
        fi
    done
}

enterDIR

This script is pretty clunky, since I only just started dipping into Bash. The problem (or at least where I think it is) comes from the if [ "$DIR" == "." ]; then line - looking at my output when running the script, it doesn't seem to filter it.

How do I filter out (ignore) the current directory?

4
  • One = for [ ...
    – Jeff Schaller
    Jan 22, 2016 at 15:31
  • Can't you use something like find . -maxdepth 1 -name "*.flac"?
    – pfnuesel
    Jan 22, 2016 at 15:33
  • 1
    You'll want to read mywiki.wooledge.org/BashFAQ/001 -- don't use for to iterate over lines. Jan 22, 2016 at 15:34
  • I think find . -type f -name "*.flac" would suffice. Let find delve into your directories. Jan 22, 2016 at 15:36

2 Answers 2

5

You can filter it in find by using -mindepth option. Like this:

function enterDIR {
    find . -mindepth 1-maxdepth 1 -type d | while read DIR ; 
    do 
        #recurse into every directory below top-level directory
        cd "$DIR/"
        enterDIR
    done

    createDirectory
    convertFLAC
}

But the whole script doesn't look like a good solution.

If I understand your idea correct, you want to walk through the whole directory tree, create there new directory, convert flac to mp3 if any and copy all non-flac files to a new dir. I would do that this way:

find . -mindepth 1 -type -d -exec mkdir -p {}/originalFLAC/Music \+
find . -type f -iname "*.flac" -exec ffmpeg -i {} -ab 320k -map_metadata 0 {}.mp3 \;
find . -type f ! -iname "*.flac" | while read file ; do cp -v "$file" "$(dirname "$file")"/originalFLAC/Music/ ; done
7
  • +1 for giving the actual solution: using find for what it's for and not recurse manually into the directories.
    – lgeorget
    Jan 22, 2016 at 15:50
  • Please demonstrate good practices: mywiki.wooledge.org/DontReadLinesWithFor Jan 22, 2016 at 15:56
  • I realize that, but you could take that one extra step Jan 22, 2016 at 16:00
  • well, maybe you're right. thx for comment. answer is updated.
    – rush
    Jan 22, 2016 at 16:01
  • 1
    ! means not. therefore find . -type f ! -iname "*.flac" means find all files with name not matching to .flac (i before name means case insensitive)
    – rush
    Jan 22, 2016 at 16:10
-1

try replacing this

for DIR in "$(find . -maxdepth 1 -type d)"

with this

for DIR in "$(find . -maxdepth 1 -type d | grep -v "\.$")"

. is interpreted as "any" single character in regex. So it has to be escaped with backslash. Also since all your lines will start with a dot character, you will need to find the line that has the dot and only the dot. Hence the end of line character $.

at this point, you should not need the if block below:

if [ "$DIR" == "." ]; then  #avoid current directory infinite loop
    continue
fi
1
  • find . -maxdepth 1 -type d -not -name . Jan 22, 2016 at 15:37

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .