1

I'm trying to convert flac files into wav files using ffmpeg. The flac files are located in various subdirectories.

/speech_files
/speech_files/201/speech1.flac
/speech_files/201/speech2.flac
/speech_files/44/speech45.flac
/speech_files/44/speech109.flac
/speech_files/66/speech200.flac
/speech_files/66/speech33.flac

What I want after the script runs is the following

/speech_files
/speech_files/201/speech1.wav
/speech_files/201/speech2.wav
/speech_files/44/speech45.wav
/speech_files/44/speech109.wav
/speech_files/66/speech200.wav
/speech_files/66/speech33.wav

I can get my script to work within one directory but I'm having a hard time getting it to run from the top level directory (speech_files) and work it's way through all the subdirectories. Below is the script I'm using.

#!/bin/bash

for f in "./"/*
do
    filename=$(basename $f)
    if [[ ($filename == *.flac) ]]; then
        new_file=${filename%?????}
        file_ext="_mono_16000.wav"
        wav_file_ext=".wav"
        ffmpeg -i $filename $new_shits$wav_file_ext
        ffmpeg -i $new_file$wav_file_ext -ac 1 -ar 16000 $new_file$file_ext
        rm -f $filename
        rm -f $new_file$wav_file_ext
    fi
done
user2743
  • 1,423
  • 3
  • 22
  • 34

2 Answers2

0

Using bash only :

#!/bin/bash

DIR="/.../speech_files"

process() {
    filename=$(basename "$1")
    # ...
}

for f in n "${DIR}"/*/*.flac; do
    process "$f"
done

Using find which is recursive and more efficient to do that kind of task to me :

find "${DIR}" -type f -a -iname "*.flac" -exec ... {} \;
Idriss Neumann
  • 3,760
  • 2
  • 23
  • 32
0

Use find from the top level directory and filter by using *.flac.

for f in $(find . -name "*.flac"); do
    echo "$f" # f points to each file
    # do your logic here
done
apatniv
  • 1,771
  • 10
  • 13
  • No need to use a `for` loop to iterate on a `find` output, you have the `-exec` option which is a lot safer. `for i in $(command)` might cause bugs when the filename contains some spaces for example. – Idriss Neumann Jun 17 '18 at 15:04
  • Yes, there are better options to make something faster. If writing faster code is the only criteria, then I would ask him/her in something like "Java" or c++ and do all the hard work. – apatniv Jun 17 '18 at 15:06
  • It's not only a matter of doing things faster, `for i in $(command)` is a bad practice that often cause bugs (for example it's not working when a filename contain spaces). It's also a matter of not re-inventing the wheel: if you choose to use `find` the use `find` completely. – Idriss Neumann Jun 17 '18 at 15:12
  • If you really need to iterate on an output of command (it's not the case here), there are many safer ways and I advice you to read this : https://stackoverflow.com/a/19607361/2900196 – Idriss Neumann Jun 17 '18 at 15:16
  • 1
    I found a nice answer here: [How to loop through file names returned by find?](https://stackoverflow.com/a/9612232/6176817) – PesaThe Jun 17 '18 at 15:19
  • @PesaThe Indeed :) – Idriss Neumann Jun 17 '18 at 15:24