1

help. everything i've tried has failed. I'm trying to fix up my video collection and lots of them have spaces in the names/etc I want to transcode them and I've written the script below, but its failing. 2 of the filenames I'm using for testing are "13 Eerie (2013).avi" and "Ace.Ventura.When.Nature.Calls.1995.720p.WEB-DL.x264-mSD.mkv"

i have tried several things from using print0 on find to mangling the IFS. any assistance would be appreciated. This current version for some reasons separates everything on the e character


convert.sh

#!/bin/sh

OUTDIR="./done/"
LOGDIR="./logs/"
BACKUPDIR="./backup/"

# deal with spaces
SAVEIFS=$IFS
IFS=$(echo -en "\n")

# pull all files except MP4 or scripts in the CURRENT DIR only
for FULLFILENAME in `find . -maxdepth 1 -type f -not -iname "*.sh" -not -iname "*.mp4" -print`
do
    # extract the file extension
    filename=$(basename "$FULLFILENAME")
    ext="${filename##*.}"
    filename="${filename%.*}"

    # use handbrake to convert to x264
    HandBrakeCLI -i "$FULLFILENAME" -o "$OUTDIR$filename.mp4" -e x264 -q 22 -r 29.97 -B 64 -O 2>$LOGDIR$filename.log

    # move the original file to a backup
    mv "$FULLFILENAME" $BACKUPDIR
done

#restore the field separator
IFS=$SAVEIFS

1 Answers1

2
  • Don't use command substitution of find
  • Don't use for loop
  • Use process substitution to get output from find
  • Use -print0 option and read using while loop
  • Better to avoid uppercase variable names
  • Use bash shebang

Code:

#!/bin/bash

outdir="./done/"
logdir="./logs/"
backupdir="./backup/"


# pull all files except MP4 or scripts in the CURRENT DIR only
while IFS= read -r -d '' fullfilename
do
    # extract the file extension
    filename="$(basename "$fullfilename")"
    ext="${filename##*.}"
    filename="${filename%.*}"

    # use handbrake to convert to x264
    HandBrakeCLI -i "$fullfilename" -o "$outdir$filename.mp4" -e x264 -q 22 -r 29.97 -B 64 -O 2>"$logdir$filename.log"

    # move the original file to a backup
    mv "$fullfilename" "$backupdir"
done < <(find . -maxdepth 1 -type f -not -iname "*.sh" -not -iname "*.mp4" -print0)
anubhava
  • 761,203
  • 64
  • 569
  • 643
  • 1
    [Don't read lines with `for`](http://mywiki.wooledge.org/DontReadLinesWithFor) and [Bash FAQ 001](http://mywiki.wooledge.org/BashFAQ/001) are relevant readings for the listed suggestions. – Etan Reisner Mar 17 '16 at 15:12
  • removed previous response, I did more reading on process substitution and I get the syntax now, but its not working with a redirection unexpected error – James Wilson Mar 17 '16 at 15:38
  • @JamesWilson: Use `#!/bin/bash` at the top as in edited answer. – anubhava Mar 17 '16 at 15:50
  • 1
    @anubhava - you are my savior sir. its weird that my sh links to bash but manually specifying it fixed it. +1Beer – James Wilson Mar 17 '16 at 17:17
  • @anubhava Sadly, I cannot accept this, it only ran the 1st item. but its a massive step in the right direction, I'm going to do more reading and see if i can figure out why, but please do the same as you clearly have more bash knowledge than I – James Wilson Mar 17 '16 at 18:56
  • Run this command: `while IFS= read -r -d '' fullfilename; do echo "$fullfilename"; done < <(find . -maxdepth 1 -type f -not -iname "*.sh" -not -iname "*.mp4" -print0)` and check the output – anubhava Mar 17 '16 at 19:04
  • yes, that does present both testing files, and when run in the media folder it lists everything (tested by using wc -l) but when i ran it as a script, the 1st video was converted, then it exited as successful. – James Wilson Mar 17 '16 at 19:11
  • 1
    to add to the confusion, I comment out the HandbrakeCLI command and added a echo "Converting $fullfilename" and it acts like both, but when handbrake runs it seems to kick out. this would elude to its a handbrake thing, not the script. I'm accepting this as a solution. – James Wilson Mar 17 '16 at 19:24