Batch File Loop Skip File if name contains
Asked Answered
G

5

6

I am creating this batch file, that works with handbrakecli, to batch convert avi to mp4.

However I am stuck in how to continue the loop and skip the current file inside a loop.

FOR /R "%somepath%" %%G in (*.avi) DO (

rem skip if filename contains word trailer

rem skip if file name contains word sample

rem do conversion
)

This currently doesn't work in skipping the files that contain trailer or sample

I have tried using find or findstr and both fail to skip.

    echo "%%G" | c:\windows\system32\findstr /i "trailer" > NUL
    If %ERRORLEVEL% EQU 1 set skip Yes

Here is for sample.

    echo "%%G" | c:\windows\system32\findstr /i "sample" > NUL
    If %ERRORLEVEL% EQU 1 set skip Yes

If a file contains either trailer or sample, I do not want to do any handbrakecli conversions, but to just skip it.

I do echo's to display which files get converted, and it does include files with Sample or sample in the name.

I have tried using find or findstr and both fail to set skip to yes

if skip == No do ( rem do conversion )

I only want to convert non-trailer/sample avi files.

Thank you for your time.

Graben answered 3/6, 2013 at 4:54 Comment(2)
pastebin.com/qY2u4HX2 This has all the current code updated with suggestions below.Graben
Also a really dumb question, not sure why but I am required to always specify the path for find or findstr, and is this a path error, or what? Just curious.Graben
A
8

try this, put your conversion commands in the loop and remove the word echo before handbrakecli if the output is OK:

@echo off &setlocal
FOR /R "%somepath%" %%G in (*.avi) DO (
    set "fpath=%%G"
    set "fname=%%~nG"
    setlocal enabledelayedexpansion
    if "!fname!"=="!fname:trailer=!" if "!fname!"=="!fname:sample=!" (
        echo handbrakecli.exe "!fpath!" &rem put your conversion  command here
        >>"logfile.log" echo !fname!
    )
    endlocal
)

The file name+file path is in the variable "!fpath!".

Added some code concerning the needs of the OP:

@echo off &setlocal
rem replace avi with mp4 files in my movie folder
rem grab 4 random folders with avi in them and no mp4

rem Settings for this Batch File
set "moviepath=H:\Movies"
set "logfile=C:\Documents and Settings\%USERNAME%\LogFiles\avi_converter.log"

rem check if log file exists
if not exist "%logfile%" echo(>"%logfile%"

rem create empty convert file
copy nul "convert_movies.bat" >nul 2>&1

rem add echo off
echo @echo off >>"convert_movies.bat"

rem set counter
SET /A COUNT=1

FOR /R "%moviepath%" %%G in (*.avi) DO (
    set "fpath=%%~fG"
    set "fname=%%~nG"
    setlocal enabledelayedexpansion

    rem check if count greater than 4
    if !COUNT! gtr 4 goto:eof

    if "!fname!"=="!fname:trailer=!" if "!fname!"=="!fname:sample=!" (
        rem echo handbrakecli.exe "!fpath!" &rem put your conversion  command here

            rem Send File To HandBrakeCLI
            CALL :DOHandBrakeCLI "!fpath!"

            rem Delete File
            CALL :DeleteOldFile "!fpath!"

            rem Add Log Entry
            CALL :LogEntry "!fpath!"

            rem add line break space
            echo( >>"convert_movies.bat"

            endlocal
            rem increment counter
            SET /A COUNT+=1

    ) else endlocal  
)
rem end main program, to close cmd window replace it with EXIT
goto:eof

:DOHandBrakeCLI
rem skip if the parameter is empty
IF "%~1"=="" goto:eof
For %%A in ("%~1") do (
    Set "Folder=%%~dpA"
    Set  "Name=%%~nxA"
)
rem echo %Folder%%Name%
echo start /b "" "c:\handbrakecli\HandBrakeCLI.exe" -i "%~1" -o "%Folder%%~n1.mp4" --preset="High Profile">>"convert_movies.bat"
exit /b

:DeleteOldFile
rem skip if the parameter is empty
IF "%~1"=="" goto:eof
For %%A in ("%~1") do (
    Set "Folder=%%~dpA"
    Set "Name=%%~nxA"
)
rem sends parameters to deletefile which will make sure new file exists before deleting old one
echo c:\projects\deletefile.bat "%~1" "%Folder%%~n1.mp4">>"convert_movies.bat"
exit /b

:LogEntry
rem skip if the parameter is empty
IF "%~1"=="" goto:eof
echo "%~1">>"%logfile%"
exit /b
Aubry answered 3/6, 2013 at 5:21 Comment(6)
I am using this loop to create a secondary batch file, that will contain the list of files to be converted, and then delete the originals, afterwards. Will this affect my ability to echo to these commands to the secondary batch file?Graben
@Graben - I made an edit: 1) put a log command in 2) bug fixed (put endlocal after first closing parentheses)Aubry
Check my pastebin, to see the code I am using combined with the code you suggested. I already had log file commands, to help log, handle deleting files. It's like 90% done, and thank you so much fyi. Now two things left, limit the loop to only x number times, so that I don't overload my pc converting too many, and handling file names with unusual characters, such as asian languages. Any thoughts?Graben
@Graben - made an edit and inserted your code with some improvements.Aubry
I get a few error messages that say The system can not find the path specified. Also it creates the batch file, but adds a blank line at the very top above the echo off statement. What is an acceptable way to offer you credit and thanks for your help. I plan to put this as a bundle on github, to help people gradually convert their movies/tv shows to mp4 format. How would you prefer to be mentioned?Graben
@Graben - I made some more edits. I created the same paths here and got no error message. You can put my name in the script, if you want so :)Aubry
D
3

This should work:

@echo off
FOR /R "%somepath%" %%G in (*.avi) DO (
echo "%%~nG" |findstr /i "trailer sample">nul || (
  rem do conversion
 )
)
Deprived answered 3/6, 2013 at 7:13 Comment(2)
+1, good idea, but findstr may be slower than if ... if.... And %%G contains the full path.Aubry
Thanks for your comments - I replaced it with %%~nG . Findstr will certainly be slower but I suspect each AVI encode will take longer than an hour, so time isn't a factor. :)Deprived
H
2

It's difficult to see where your post is pseudocode and where actual code.

The first sample contains only REM statements, so it's not surprising it apparently does nothing.

Your second and third sample are effectively identical - the only difference is the target string. It's not surprising that the variable skip isn't set to Yes since the correct syntax is

if %errorlevel% equ 0 set skip=Yes

The syntax you've posted will REPORT that skip is not defined - it ignores the Yes

HOWEVER this syntax is only usable OUTSIDE of a "block statement" - that is, a multiple-instruction statement (enclosed in parentheses) or cascaded&by&ampersands. Batch first PARSES a complete statement - from the FOR or if through to the appropriate closing-parenthesis and THEN executes it. As part of the PARSING phase, any %var% - including %errorlevel% is replaced by its value as it stands at the time the entire statement is parsed - not as it changes due to the operation of the for.

In order to use the value as it changes, you need to use

if errorlevel 1 (do_something) else (do_something_else)

where do_something and do_something_else) may themselves be compound statements.

OR

if defined variable (do_something) else (do_something_else)

where the variable either is defined or not

OR

setlocal enabledelayedexpansion
....
if !errorlevel! equ x (do_something) else (do_something_else)

OR

 if !var! neq something (do_something) else (do_something_else)

But it's quite possible that

FOR /R "%somepath%" %%G in (*.avi) DO (
 echo(%%G|findstr /i "sample trailer" >nul
 if errorlevel 1 echo %%G
)

will give you an appropriate skeleton.

Echo the filename through FINDSTR and look for "sample" or "trailer" /i case-insensitive. Findstr sets errorlevel 0 if either target string is found, 1 otherwise - and the if errorlevel x syntax works on the dynamic value of errorlevel within a loop.

Hawkeyed answered 3/6, 2013 at 6:12 Comment(0)
N
1
@ECHO on &SETLOCAL

REM This script was inspired by Endoro's expanded script
(https://mcmap.net/q/1640863/-batch-file-loop-skip-file-if-name-contains).

REM This batch script will recursively search for all .mp4 files that don't
have (x265) in the file name. Any valid results will be encoded with x265
using FFmpeg. The original .mp4 file will remain unchanged in it's original
folder with the new x265 version.

REM Example: %PATH%\A.mp4 > %PATH%\A(x265).mp4

REM If you don't have ffmpeg.exe on your PC you must download or build it
with Microsoft Visual Studios. I recommend you download and run media
autobuild suite on GitHub: (https://github.com/jb-alvarado/media- 
autobuild_suite).

REM Once ffmpeg is compiled/downloaded make sure to set it's folder path as
an environmental variable in Windows before running the script. Change the
script's working directory to your .mp4 files root folder using the "cd" 
command.

REM !!BEGIN SCRIPT!!

cd /d %USERPROFILE%\Desktop\Vids\
REM or perhaps use [cd /d %OneDrive%\Desktop\Vids]

REM Set mp4PATH to the root folder you wish to recursively search.
SET "mp4PATH=%USERPROFILE%\Desktop\Vids\"

REM Create empty convert file.
COPY NUL "convert_movies.bat" >NUL 2>&1

REM Add ECHO off.
ECHO @ECHO off >>"convert_movies.bat"

REM Recursively search root folder.
FOR /R "%mp4PATH%" %%G IN (*.mp4) DO (
    SET "fpath=%%~fG"
    SET "fname=%%~nG"
    SETLOCAL enabledelayedexpansion

REM Ignore all files that have "(x265)" in the file name.
IF "!fname!"=="!fname:*(x265)=!" (
    CALL :DO_FFmpeg_CLI "!fpath!"
    ECHO(>>"convert_movies.bat"
        ) ELSE ENDLOCAL
    )
)
GOTO:EOF

REM CALL variables for use in FFmpeg's command line.
:DO_FFmpeg_CLI
IF "%~1"=="" GOTO:EOF
FOR %%I IN ("%~1") DO (
    SET "Folder=%%~dpI"
    SET "Name=%%~nxI"
)

REM Export info to "convert_movies.bat and run ffmpeg.exe's command line in the cmd.exe window.
ECHO ffmpeg -y -i "%~1" -c:v libx265 -preset slow -crf
18 -c:a aac "%Folder%%~n1(x265).mp4">>"convert_movies.bat" && ffmpeg |
ffmpeg -y -i "%~1" -c:v libx265 -preset slow
-crf 18 -c:a aac "%Folder%%~n1(x265).mp4"
EXIT /B
PAUSE
Nurture answered 29/10, 2018 at 5:59 Comment(0)
R
0

The Batch file below solve the original question AND limit the number of converted files to a given number (that does not appear in the original question):

@echo off
setlocal EnableDelayedExpansion
rem Insert in the next line the list of files to skip
set skip=/trailer/sample/
set count=0
FOR /R "%somepath%" %%G in (*.avi) DO (
   if /I "!skip:/%%~nG/=!" equ "%skip%" (
      echo Current file name is not in skip variable
      echo Do conversion on: %%G
      set /A count+=1
      if !count! equ 20 goto :endLoop
   )
)
:endLoop
echo Converted files: %count%
Roast answered 3/6, 2013 at 8:22 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.