Home > Software engineering >  Using mkdir and ffmpeg in a batch script on recursive folders
Using mkdir and ffmpeg in a batch script on recursive folders

Time:03-22

I have many folders with .mp4 files. I wrote a script that takes the mp4 files and converts them into 1 jpeg image per frame. Critically, the output of this script (retained file name, with _frame number appended to the end) goes into a newly created folder with the file basename:

#!/bin/bash
for f in *.mp4; do mkdir -p "${f%.*}" && ffmpeg -i ${f} -start_number 000 "${f%.*}/${f}_d.jpg"; done

I can run this for every parent folder one at a time no problem but I would like to just run it once and get it to run recursively.

I changed the code to:

#!/bin/bash
for f in *.mp4/; do mkdir -p "${f%.*}" && ffmpeg -i ${f} -start_number 000 "${f%.*}/${f}_d.jpg"; done

and tried playing with the mkdir part (by adding ./) but no matter what I do, I get the following error.

mkdir: cannot create directory ‘*’: Invalid argument

Is there anything I need to do to allow mkdir to create the appropriate new folders in their respective subfolders?

The file structure is as follows:

parent folder
    └── videos_1
        ├── videos_1_basename_1.mp4
        └── videos_2_basename_2.mp4
    └── videos_2
        ├── videos_2_basename_1.mp4
        └── videos_2_basename_2.mp4
.sh script

CodePudding user response:

You can use the globstar bash option:

#!/usr/bin/env bash

shopt -s globstar
for f in **/*.mp4; do
  d="${f%.mp4}"
  if mkdir -p "$d"; then
    ffmpeg -i "$f" -start_number 000 "$d/${f}_d.jpg"
  else
    printf 'could not mkdir %s\n' "$d"
  fi
done

CodePudding user response:

*.mp4/ would, due to the appended /, expand to all directories where the name ends in .mp4. If you don't have directories with such a name, you don't get any wildcard expansion. f is therefore set to the string *.mp4/ and ${f%.*} yields a lone *, as you can try by yourself on the command line. It seems that mkdir refuses the creation of directory with such a weird name; I would consider this a feature instead of a bug.

There is no recursion in your code with respect to the directories. You could do a

for f in videos_*/*.m4a

inside your parent folder. Of course f will then also contain the name of the respective subdirectory (for instance videos_1/videos_1_basename_1.m4a), and you have to adapt your script to this fact.

  • Related