I have multiple folders each one include the following

  • a video file xFilename.mp4
  • a folder named Subs, which include many srt files xFilename.srt.

How can I use bash to execute an mkvmerge command for each folder to merge each mp4 file with all the srt files in its Subs folder and output an mkv file with the same name as the mp4 file.

Something like

for dir in ./* :
   if (there is an mp4 file) :
       name = "mp4 file name without the extension, dunno how to do that"
       mkvmerge -o ./"$dir"/"$name".mkv ./"$dir"/"$name".mp4 "$dir"/Subs/*.srt

How to write that in the terminal?

1 Answer 1


Modifying your pseudo-code:

for mp4file in */*.mp4; do
    [ ! -f "$mp4file" ] && continue
    mkvmerge -o "${mp4file%.mp4}.mkv" "$mp4file" "${mp4file%/*}/Subs"/*.srt

What's happening here is that I iterate over all MP4 files found in any subdirectory of the current directory, and for each found file I execute that mkvmerge command.

The test, [ ! -f "$mp4file" ], is there to catch the case where no files matches the given pattern. If the condition is true (the variable contains a name that does not refer to an existing regular file or symbolic link to a regular file), then this iteration is skipped using continue.

The expansion ${variable%pattern} will remove the shortest substring matching pattern from the end of the value of the variable variable. This means that given that mp4file contains the pathname of some MP4 file, then

  • ${mp4file%.mp4}.mkv removes the .mp4 from the end of the pathname in mp4file, and adds .mkv.

  • ${mp4file%/*}/Subs removes the filename portion of the pathname, as well as the last /, in mp4file and adds /Subs to the end of it.

You must log in to answer this question.

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