I need to batch convert some video files from H264 to H265. I know my ffmpeg command line, I have a csv of file names with a relative path (I need the filelist to drive it as some files in the location are already converted). The only thing I'm having trouble with now is driving the conversion from the filelist.

My command line:

cat mkv-analysis.csv | while read file; do $(ffmpeg -i '$file' -c:v libx265 -x265-params crf=23 -preset medium -c:a copy -c:s copy '${file%.mkv}_new.mkv'); done;

And a sample of data:


So, can anyone tell me what I'm doing wrong, as I get "$file: No such file or directory" messages?

  • If any of the answers has solved this problem, please Accept it with the checkmark. Thank you!
    – Jeff Schaller
    Feb 12, 2017 at 16:51

2 Answers 2


You are using single quotes around $file which means that the variable isn't expanded:

$ var="foo"
$ echo "$var"
$ echo '$var'

So, the command you are looking for is (with a few more improvements):

while read -r file; do 
    ffmpeg -i "$file" -c:v libx265 -x265-params crf=23 -preset medium -c:a copy -c:s copy "${file%.mkv}_new.mkv"
done < mkv-analysis.csv 

Note that there's no need for cat and absolutely no point in running the command as a command substitution ($(command)). That's only needed when you want to capture the output of a command in a variable.


I think you need something like:

$ cat mkv-analysis.csv | xargs -I % ffmpeg ...

% is the argument, a file path in your case.

assuming that mkv-analysis.csv has the format:


If the format is different you'll have to prepare it with awk: E.g.:

$ awk '...awk script...' mkv-analysis.csv | xargs ffmpeg ...

The main thing is that xargs feeds ffmpeg with files and at this stage ffmpeg should be able to find the file.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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