0

I want to convert a bunch of mkvs to mp4s with the following command:

for i in $(ls *mkv); do ffmpeg -i $i -vcodec copy -acodec copy $i.mp4; done;

However, the filenames have whitespaces and hyphens in them, so the command does not work properly. (When I manually replace The File - 01.mkv with The\ File\ \-\ 01.mkv, the same command works).

What's the best way to get this to work?

Anthon
  • 79,293

1 Answers1

8

You need to quote the variables and avoid the command substitution:

for i in ./*.mkv; do ffmpeg -i "${i}" -vcodec copy -acodec copy "${i}.mp4"; done

See When is double-quoting necessary? for a detailed explanation of quoting.

While I'm at it, the above produces files with a .mkv.mp4 extension; to fix that:

for i in ./*.mkv; do ffmpeg -i "${i}" -vcodec copy -acodec copy "${i%%.mkv}.mp4"; done
Stephen Kitt
  • 434,908
  • 2
    Or use zsh that doesn't have all those misfeatures: for i (./*.mkv) ffmpeg -i $i -vcodec copy -acodec copy $i:r.mp4 – Stéphane Chazelas Mar 06 '15 at 15:06
  • @StéphaneChazelas - it's possible that neither method is foolproof. Apparently ffmpeg interprets its own quotes - single quotes, backslashes, and double-quotes, though at a glance it appears it interprets double-quotes as the harder form. Note that you may need to add a second level of escaping when using the command line or a script, which depends on the syntax of the adopted shell language. – mikeserv Mar 06 '15 at 17:55