2

I'm trying to convert a bunch of .aac files to .mp3 files in separate subdirectories in a directory. This is the code I've written:

for dir in */
do
    OUTPUT_DIR=./mp3
    mkdir "$OUTPUT_DIR"
    for i in *.aac;
      do name=`echo "$i" | cut -d'.' -f1`
      echo "$name"
      ffmpeg -i "$i" -vn -ar 44100 -ac 2 -b:a 192k "$OUTPUT_DIR/${name}.mp3"
    done
done

However this just try to run the commands in the outside directory and gives an error. I'm new at bash so it might be a very simple mistake I'm not seeing.

0

2 Answers 2

4

How to loop through files in subdirectories?

Read ex How to loop through a directory recursively to delete files with certain extensions

This is the code I've written:

Check your scripts with http://shellcheck.net

Do not use `. Use $(...) instead.

To get file name and dir see basename and dirname commands. Your name=echo "$i" | cut -d'.' -f1 will fail when directory has a dot.

Use printf "%s\n" "$i" or in bash <<<"$i" here string instead echo "$i" |. See ex. https://unix.stackexchange.com/questions/65803/why-is-printf-better-than-echo .

Prefer lower case variables in your scripts.

so it might be a very simple mistake I'm not seeing.

You are not changing the direcotry at all. You need to cd somewhere to that dir and then cd - back (or pushd + popd). But just reference directories relative to your current dir anyway. Maybe something along:

for dir in ./*/; do
    # create the directory in dir
    output_dir="./$dir/mp3"
    mkdir "$output_dir"
    # find files aac inside $dir/
    for i in "$dir"/*.aac; do
       name=$(basename "$i" .acc)
       echo "$name"
       ffmpeg -i "$i" -vn -ar 44100 -ac 2 -b:a 192k "$output_dir/${name}.mp3"
    done
done
Sign up to request clarification or add additional context in comments.

1 Comment

This answer is so detailed and clear, definitely learned something and solved the problem, thank you!
2

You may want to use find to recursively find all files in all subdirectories of a directory.

Here's an example (it assumes you also want to recreate the subdirectories in the output directory).

OUTPUT_DIR=./mp3

for item in $(find . -type f -name *.aac); do
    name="$(basename $item .aac)"
    subdir="$(dirname $item)"
    mkdir -p "$OUTPUT_DIR/$subdir"
    ffmpeg -i "$name" -vn -ar 44100 -ac 2 -b:a 192k "$OUTPUT_DIR/$subdir/$name.mp3"
done

1 Comment

I didn't even know find existed, I'll read up on it, thank you!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.