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?

marked as duplicate by jasonwryan, Anthon, John WH Smith, Gilles command-line Mar 7 '15 at 18:11

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

  • This is a classic XY problem. You wanted to do something with files with spaces in their names, but you guessed at a solution and then titled your question with a reference to your guessed solution. – G-Man Mar 7 '15 at 0:57
  • I don't think any of the answers to that question actually answer this one, though. They're all about find. – Michael Homer Mar 7 '15 at 4:05

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
  • 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 6 '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 6 '15 at 17:55

Not the answer you're looking for? Browse other questions tagged or ask your own question.