Search code examples
bashvideodirectorysubdirectory

How to recursively apply command


I'm still a newbie in bash and I'm trying to create a bash script in order to transcribe all the videos and audio files I have. Any file extension. So far I can transcribe all the video files from the same folder I run the bash script.

For example. The command below allows me to transcribe all the video files in the same folder where the bash script is located.

for file in *
do
  autosub -S de -D de "$file" >> results.out
done

I'm trying to make the same command recursively so I don't have to do it on each folder each time.

for file in \*
do
  autosub -S de -D de "$file" >> results.out
done

So I've changed it a bit the command above and it still doesn't work. It tries to apply the command recursively but to folders instead of files. It only applies the command to files when it's located inside the same folder as the bash script.

What I'm trying to achieve is: Run a command with autosub -S de -D de $file for every file (any extension. If it can't be transcribed, it will skip automatically. You don't have to write that in the bash script since autosub already skips)

I want to transcribe all the video files inside a folder structure like that:

Folder 1
------SubFolder 2
----------------SubFolder 3\video.avi
Folder 2\video.mp4
Folder 1
--------SubFolder\video.mkv

Solution

  • Typically, one would use find for this:

    find . -type f -execdir autosub -S de -D de {} \; >> results.out
    

    This will execute your command for every file (notice: -type f) located below your current directory (notice .). The command is executed each time inside the directory the file is in (notice: -execdir). That means your command will receive filenames like ./video.avi, ./video.mp4, and not the complete path relative to your initial directory. This is considered safer than -exec. All results are appended to one file, ./results.out.


    Alternatively, if you're using bash >= 4.0, you can enable globstar with:

    shopt -s globstar
    

    and then use ** which expands recursively:

    for file in **
    do
        autosub -S de -D de "$file" >> results.out
    done