leovigildorex
leovigildorex

Reputation: 21

Skip files in loop which already have FINAL in their name

I want to change the CODEC H264 to H265, the archives which have H264, they have the following format: archive.mp4

and once is changed the archive has this format: archiveFINAL.mp4

This is my code:

#!/bin/bash
find *.mp4 | while read -r file; do 
if [ "${file%.*}" != "${file%.*}FINAL" ]; then
    ffmpeg -i "${file%.*}".mp4 -c:v libx265 -vtag hvc1 "${file%.*}FINAL".mp4
else
    echo "There is not archives to convert"
fi;
done

I made test with archiveFINAL.mp4 and the script works when in theory if the name is archiveFINAL.mp4 it doesn't have to work. The problem is the code works without discriminate between archive.mp4 and archiveFINAL.mp4. And I don't want to do it if the name of the archive finish in FINAL.mp

Upvotes: 0

Views: 31

Answers (3)

KamilCuk
KamilCuk

Reputation: 141473

Use find. It's the tool to... find stuff.

find . -maxdepth 1 -type f -name '*.mp4' '!' -name '*FINAL.mp4' |
while IFS= read -r line; do
   ffmpeg -i "${file%.*}".mp4 -c:v libx265 -vtag hvc1 "${file%.*}FINAL".mp4
done

The

find *.mp4

is equal to

find somefile.mp4 otherfile.mp4 otherfile.mp4 ....

It's not using find as intended at all - *.mp4 is expanded by the shell. Would be better to use shopt -s nullglob with for i in *.mp4 instead.

To find all files named *.mp4, do find . -name '*.mp4'. Note quotation. The -maxdepth 1 limits found files to only current directory.

Upvotes: 0

Bruce Wen
Bruce Wen

Reputation: 121

To check if the file name ends with "FINAL.mp4", you can just do it like this:

echo "$file_name" | grep -Eq '.+FINAL\.mp4$'
if [ $? -eq 0 ];then
    // do what you want here
fi

Upvotes: 0

tripleee
tripleee

Reputation: 189607

Your conditional probably doesn't do what you want, and looks much too complex anyway.

find *.mp4 | while read -r file; do 
  if [ "${file%FINAL.mp4}" = "$file" ]; then
    ffmpeg -i "$file" -c:v libx265 -vtag hvc1 "${file%.mp4}FINAL".mp4
  else
    echo "$file is already converted" >&2
  fi
done

I would probably use a case statement instead, but this attempts to change as little as possible. The case syntax might look scary if you are not familiar with it;

  case $file in
   *FINAL.mp4) echo "$file is already converted" >&2;;
   *) ffmpeg ...;;
  esac

By the way, notice that this will recurse into subdirectories; if that's not desired, you want simply for file in *.mp4; do...

Upvotes: 1

Related Questions