Caspershire Meta

sequential execution with find command

The way I dealt with encoding bunch of files with ffmpeg in a folder was to use bash script. Before executing the bash script, I had to create 2 directories, queue and encoded (their functions are self-explanatory). The bash script has this commands:

# defining output
inputdir=queue
outputdir=encoded

if [ -d $outputdir ]
 then
echo "Directory exists, now converting files"
 else
mkdir $outputdir
echo "created output directory"
fi


# start the conversion for mov files
for k in $inputdir/*.mov; do
	if [ -e "$k" ]; then
	    file=`basename "$k" .mov`
		ffmpeg -i "$k" -c:v libx264 $outputdir/"$file.mp4"
	fi
done

# delete all soure files inside the inputdir
while true; do
    read -p "Continue deletion? Enter [y]es or [n]o:  " yn
    case $yn in
        [Yy]* ) rm $inputdir/*; break;;
        [Nn]* ) exit;;
        * ) echo "Please answer yes or no.";;
    esac
done

Pretty neat, except that it adds another layer of work by having to locate this script or change the file extension to suit my needs. And adding another layer of work could sacrifice productivity. I don’t want to sacrifice productivity, and I want something much more efficient, ideally without using script.

I was looking for a simpler way to encode bunch of files in a specific directory, and I found linux find command. If you are running on OSX, the native find command doesn’t have the same as the Linux version does. You can install it though by running brew install findutils, and invoke it with gfind instead of find.

case 1: encoding files

find . -name "*.flac" -exec ffmpeg -i {} -c:a libmp3lame -ab 256 {}.mp3 \;
rename 's/\.flac//' *.mp3

I am bad at explaining scripts with spaghetti characters, so I am going to simplify it like this:

find . -name "*.flac" will list all files with *.flac extension, then with -exec, it tells the find to let another program, in this case ffmpeg, to run operation(s) on them. Here, ffmpeg is encoding the files from flac to mp3 with their names retained in the form of filename.flac.mp3. Cleanup can be done with rename command (on OSX, install rename with brew).

Done.

case 2: uploading files to BackBlaze B2

I thought by running find . -name "*.ext" -exec b2 upload_file could upload my science project files without giving me headache, but it did give me headache.

Say that in my project folder I have 3 files: 001.ext, 002.ext, and 003.ext files. By running find . -name "*.ext", and then printing the list to the terminal, I will get this:

./001.ext
./002.ext
./003.ext

If we do a combination of find and b2 to upload all these files to BackBlaze

find . -name "*.ext" b2 upload_file myRepo {} {} \;

… instead of uploading these files to the root of the repo, a new directory . will be created in the root of the repo and uploaded files will in that directory instead. To fix this, the command should be like this:

find * -type f -print -exec b2 upload_file b2-repo {} {} \;

A quick analysis reveals that, when running find * -type f -print, it will print this to terminal:

001.ext
002.ext
003.ext

… and I don’t have the perfect explanation why that happens. Remember that on OSX find * -type print -exec won’t work. Instead of using find, use gfind instead.