Set filename as variable in BATCH - batch-file

Am new to this so hope someone can assist a novice. Cannot locate the answer so far. Essentially I am trying to create a watch folder which picks up new .MXF files, runs a specific command line application and renames the new file with the original filename plus _new.
#echo off
:loop
if exist "C:\Input\*.mxf" (
for %%a in ("C:\Input\*.mxf") do (
C:\BMX\bmxtranswrap -o C:\Output\NEW.mxf -t as11op1a -y 09:59:50:00 --afd 10 --pass-anc all -anc-max 2048 "%%a"
ping -n 5 localhost >nul
del "%%a"
)
)
ping -n 5 localhost >nul
goto :loop
I originally tried using %~n1 command to pass through the name which works in a CMD script I have.
C:\BMX\bmxtranswrap -o C:\Output\%~n1_NEW.mxf -t as11op1a -y 09:59:50:00 --afd 10 --pass-anc all -anc-max 2048 "%%a"
This doesn't work however. If there is a command I am missing to pass through the source filename then please let me know.
Many thanks.

You need to extract the filename without the extension in order to use it as a variable in the new name.
To get the filename you can use:
%%~ni
This should work:
#echo off
if exist "C:\Input\*.mxf" (
FOR %%i IN ("c:\Input\*.mxf") DO (
REM ECHO %%~ni - This is the filename without the extensoion for the new file
C:\BMX\bmxtranswrap -o C:\Output\%%~ni_new.mxf -t as11op1a -y 09:59:50:00 --afd 10 --pass-anc all -anc-max 2048 %%i
ping -n 5 localhost >nul
del %%i
)
)
NOTE:
I've tested the above code without the bmxtranswrap line and the new filenames were displayed as expected: test_new.mxf and test2_new.mxf

Related

Store curl command output in a variable in batch script

I tried many examples online, but was not able to make it work. I am new to this so please forgive my primitive question.
say I have this:
curl "www.google.com" -o /dev/null -s -w "%{http_code}\n"
when running this in a cmd window, it returns the response code.
200
which is as expected.
I would like to do something like this in a batch script, but also use the output of the curl command to set a variable.
All examples I found online propose:
set res = $(curl "www.google.com" -o /dev/null -s -w "%{http_code}\n")
echo %res%
pause
or like this
FOR /F "tokens=* USEBACKQ" %%F IN (`curl www.google.com -o /dev/null -s -w "%{http_code}\n"`) DO ( SET var=%%F )
ECHO %var%
pause
both did not work, my batch script closes immediately.
Any feedback or help is highly appreciated
thank you.
Thanks to #Compo, here is the formatted answer for other's benefit.
#echo off
For /F %%G In ('%__AppDir__%curl.exe -s -o NUL "www.google.com" -w "%%{http_code}\n"') Do Set "response=%%G"
echo response code is %response%
IF %response% == 200 (
ECHO was able to ping google
) ELSE (
ECHO unable to ping google
)
pause
As he has mentionned above #Compo in his comment :
"To get the result of the command as a variable at the Command Prompt, you'd use For /F"
#echo off
Title Store curl command output in a variable in batch script
Set "MyCommand=curl "www.google.com" -o NUL -s -w "%%{http_code}""
#for /f %%R in ('%MyCommand%') do ( Set VAR=%%R )
echo %VAR%
pause
Based upon your own answer code, there's no need to use a for-loop to get the result saved to a variable, and then compare that variable value with a known value. You can pipe the result through findstr to see if it matches your known value instead.
Example batch-file:
#%__AppDir__%curl.exe -s -o NUL "www.google.com" -w "%%{http_code}" ^
| %__AppDir__%findstr.exe /X "200" 1> NUL && (Echo Ping Succeeded
) || Echo Ping Failed
#Pause
It is only really one line, split for readability, so you could do it line this in cmd:
%__AppDir__%curl.exe -s -o NUL "www.google.com" -w "%{http_code}" | %__AppDir__%findstr.exe /X "200" 1> NUL && (Echo Ping Succeeded) || Echo Ping Failed
Or like this as a batch-file:
#(%__AppDir__%curl.exe -s -o NUL "www.google.com" -w "%%{http_code}" | %__AppDir__%findstr.exe /X "200" 1> NUL && (Echo Ping Succeeded) || Echo Ping Failed) & Pause
Other answers are good, but I would not use CURL to just test if we can reach a site:
#echo off
ping google.com -n 1 >nul 2>&1
if %errorlevel% equ 1 (
echo EHHH..NO Google is not down, we are
) else (
echo HURRAH MAN We are OK
)

Batch File to check text files for a string

im trying to create a batch file that goes thorugh each text file in a folder and looks for specific words such as "msg" "file" "size" in each line. If those words are found then it sends and me an email.
Im using SQL server to send the email, and im calling the email stored procedure from my batch file like this:
set MYDB= yourDBname
set MYUSER=youruser
set MYPASSWORD=yourpassword
set MYSERVER=yourservername
sqlcmd -S %MYSERVER% -d %MYDB% -U %MYUSER% -P %MYPASSWORD% -h -1 -s "," -W -Q "exec yourstoredprocedure"
I just need help writing the script which checks for specific words in each line in each .txt file
Just give a try for this batch file :
#echo off
Title Search String into text files
Set "ROOT=%~dp0"
set "String2Search=msg size file"
For %%a in (%String2Search%) do (
FOR /f "delims=" %%f IN ('dir /b /s "%ROOT%\*.txt"') DO (
(find /I "%%a" "%%f" >nul 2>&1) && ( Call :FoundString "%%a" "%%f" ) || ( Call :NoFound "%%a" "%%f" )
)
)
pause & exit
::*************
:FoundString
echo found %1 on file %2
goto :eof
::*************
:NoFound
echo no string like %1 found on file %2
goto :eof
::*************
Few suggestions as i cannot comment.I had done a project few years back and i had to do search files with a particular extension and read them to find particular words and do something with them.I remember few things only.I hope it helps you.
To find all txt files:
find /home/user/Downloads/etc -name '*txt'
To read a whole file and search for "msg" "file" "size":
while read -r LINE
do
grep -i "msg" | grep -i "file" | grep -i "size"
to check all in one line
Or you can do it executing one by one without "pipelining".
P.S I don't have linux installed otherwise I would have checked before posting.Sorry if not correct.
This should do the job:
#ECHO OFF
CD C:\wherever\your\.txt\files\are\at
FOR /R %%G IN ("*.txt") DO (FINDSTR /I /C:"msg" /C:"file" /C:"size" "%%G" >nul && GOTO match_found)
GOTO no_match
:match_found
ECHO Match found^!
set MYDB= yourDBname
set MYUSER=youruser
set MYPASSWORD=yourpassword
set MYSERVER=yourservername
sqlcmd -S %MYSERVER% -d %MYDB% -U %MYUSER% -P %MYPASSWORD% -h -1 -s "," -W -Q "exec yourstoredprocedure"
:no_match
ECHO No match found^!
PAUSE
If the batch file is in the same folder as the .txt files you can delete the CD line.
If the search should be case-sensitive remove the /I option.
To satisfy your question as asked, this should suffice:
#Echo Off
FindStr /IR "\<msg\> \<file\> \<size\>" "C:\Users\NT-Hero\*.txt">Nul||Exit /B
Rem Your 'match found' commands here
If you wanted to also search in sub-directories change the FindStr options to /SIR. (See FindStr /? for more options).

BATCH - wait for file to be complete before picking up

I have a command that watches a certain folder for new files. These files are created by a video transcoder so are locked and keep growing in size till completion.
#echo OFF
:loop
if exist "E:\OUT\*.mxf" (
for %%i in ("E:\OUT\*.mxf") DO (
C:\bmx\bmxtranswrap -o "E:\DPP_create\DPP_OUT\%%~ni.mxf" -t as11op1a -y 09:59:50:00 --afd 10 "%%i"
ping -n 5 localhost >nul
del "%%i"
)
)
ping -n 5 localhost >nul
goto :loop
Is there a way to only pick up files which are fully completed (Windows unlocked)? At the moment the next command is tripping up as it is attempting to open an incomplete file.
Any advise? Thanks.
As long as you are correct in that your transcoder has the file locked until it is complete, then the solution is actually simple.
Use redirection to test that you can open the file for writing, but don't modify it. Only process if the redirection succeeded.
Note:
You don't need your outer IF statement.
You can use an infinite FOR /L loop instead of a GOTO loop
I don't understand why you need a delay before your DEL, but I preserved it anyway.
#echo OFF
for /l %. in () do (
for %%i in ("E:\OUT\*.mxf") do 2>nul( (call )>>"%%i" ) && (
C:\bmx\bmxtranswrap -o "E:\DPP_create\DPP_OUT\%%~ni.mxf" -t as11op1a -y 09:59:50:00 --afd 10 "%%i"
ping -n 5 localhost >nul
del "%%i"
)
ping -n 5 localhost >nul
)

Using a .bat to extract text between two words

I have a media server and I'm attempting to automate ripping my collection of movies and any future movies using MakeMKV. Ripping and moving is working without a hitch. The problem I'm running into is occasionally MakeMKV doesn't assign a title to the MKVs and I end up with title00.mkv which Media Center Master obviously cannot even begin to try to match to any metadata.
MakeMKV does offer the ability to get the information from the disc which I have print to info.txt which looks like this.
MSG:1005,0,1,"MakeMKV v1.8.10 win(x64-release) started","%1 started","MakeMKV v1.8.10 win(x64-release)"
DRV:0,2,999,1,"HD-DVD-ROM HL-DT-ST BD-RE GGW-H20L YL05","FARFROMHOME_16X9","\\Device\\CdRom0"
DRV:1,256,999,0,"","",""
DRV:2,256,999,0,"","",""
DRV:3,256,999,0,"","",""
DRV:4,256,999,0,"","",""
DRV:5,256,999,0,"","",""
DRV:6,256,999,0,"","",""
DRV:7,256,999,0,"","",""
DRV:8,256,999,0,"","",""
DRV:9,256,999,0,"","",""
DRV:10,256,999,0,"","",""
DRV:11,256,999,0,"","",""
DRV:12,256,999,0,"","",""
DRV:13,256,999,0,"","",""
DRV:14,256,999,0,"","",""
DRV:15,256,999,0,"","",""
FARFROMHOME_16X9 is the label for the disc.
How can I extract this and rename my .mkv when makemkv has finished?
Here is my BAT so far (my first attempt at a .bat):
makemkvcon64 -r info disc > info.txt
makemkvcon64 --minlength=3600 mkv disc:0 all C:\Users\HTPC\MakeMKV_Temp\
START /WAIT makemkvcon64.exe
cd "c:\Program Files (x86)\FreeEject\"
FreeEject d:
move C:\Users\HTPC\MakeMKV_Temp\*.mkv C:\Users\HTPC\Movies\
Renaming the file before the move would be ideal.
Although you posted an ample description of your problem and data, you have not explained what exactly you want as result, so I must guess a couple points. The lines below extract the sixth comma-separated token from the second line of info.txt file:
for /F "skip=1 tokens=6 delims=," %%a in (info.txt) do set "discLabel=%%~a" & goto continue
:continue
echo The label of the disk is: %discLabel%
This is the output of previous lines when they are executed on your example data:
The label of the disk is: FARFROMHOME_16X9
You also have not indicated the name of the file you want to rename (before move it). Below is a possible solution to your problem that should be adjusted when previous unclear points be defined:
makemkvcon64 -r info disc > info.txt
for /F "skip=1 tokens=6 delims=," %%a in (info.txt) do set "discLabel=%%~a" & goto continue
:continue
makemkvcon64 --minlength=3600 mkv disc:0 all C:\Users\HTPC1\MakeMKV_Temp\
START /WAIT makemkvcon64.exe
cd "c:\Program Files (x86)\FreeEject\"
FreeEject d:
ren C:\Users\HTPC1\MakeMKV_Temp\TheNameHere.mkv %discLabel%.mkv
move C:\Users\HTPC1\MakeMKV_Temp\*.mkv C:\Users\HTPC1\Movies\
I've been wrangling with the same thing and created something that works fairly well.
MakeMKV uses it's own output FileName like you indicated "title00.mkv" or something similar.
I've created two(2) batch files to perform my home movie automation.
The first is "RipWorkflow_DVD.bat", which handles all the heavy lifting to call MakeMKV first to rip the content to my drive. Also in this file is a call to Handbrake to convert the MKV to MP4 (my stupid "smart" tv won't play MKV, but likes MP4)
The second batch file "OneStepDVDRip.bat" calls the first, but with parameters I choose for
a) location of the MKV
b) the output name of my MP4
c) the minLength of a track to locate and rip to MKV
Here is the code for "OneStepDVDRip.bat"
call "C:\Users\Todd\Desktop\RipWorkflow_DVD.bat" "Z:\Video\TrueStory" "E:\My Videos\Movies\Drama\True Story (2015).mp4" 3600
Here is the code for "RipWorkflow_DVD.bat"
#echo off
cls
setlocal ENABLEDELAYEDEXPANSION
SET input=%1
SET output=%2
SET minlength=%3
echo
echo %input%
echo %output%
echo
if not exist %input% ( mkdir "%input%" )
call "C:\Program Files (x86)\MakeMKV\makemkvcon64.exe" --minlength=%minlength% --decrypt mkv disc:0 0 "%input%
timeout /t 5 /nobreak
for %%F in (%input%\*.mkv) do (
echo %%~dpnxF
echo %output%
call "C:\Program Files\Handbrake\HandbrakeCLI.exe" -v1 -i %%~dpnxF --main-feature -o %output% -f mp4 --markers -e x264 -b 2000 -a 1 -E faac -6 dpl2 -R 44.1 -B 128 -D 1.75 --subtitle-forced -x ref=2:bframes=2:subme=6:mixed-refs=0:weightb=0:8x8dct=0:trellis=0
timeout /t 5 /nobreak
DEL %%F /Q
)
endlocal

Trying to use a batch file to work with filenames that have a forbidden character

Okay, a brief explanation of what I am doing: I use Windows Media Center (Windows 7) to record Jeopardy every evening. I then use Handbrake to convert the .wtv files to .mkv files and then transfer them to my NAS so I can watch them later using Plex Media Server/Center. Rather than doing this "by hand", I'm trying to automate the process using a batch file as a scheduled task. Initially, I had set up a script so that I could right-click > Send To > convert.bat and it would initiate the command-line interface for Handbrake and convert the file, move the output to my NAS, and delete the original file (worked great).
Now, what I'm doing is initiating the batch script as a scheduled task and looping through the contents of my "recorded tv" directory and looping through any .wtv files to convert/move/delete them.
The problem lies in the fact that Windows Media Center correctly names the Jeopardy files with the "!" in them (Eg: Jeopardy!_KHQ_2012_12_04_21_12_12.wtv), which completely bricks my script. The "Send To" batch file worked great, but when I loop through the *.wtv files in the directory, it returns all the filenames with the "!" stripped out which means I can't do squat with them. Files without "!" do process without a hitch.
Thanks in advance to anyone who can get me pointed in the right direction! (and if you happen to see any other areas where this script could be improved, that's fine too...)
Here is the basic code that I am attempting to use:
#echo off
setlocal ENABLEDELAYEDEXPANSION
SET count=0
SET getFolder=C:\Users\Public\Recorded TV\
SET ripFolder=C:\Rips\
SET putFolder=Z:\Videos\Recorded TV\
FOR %%F IN ("%getFolder%*.wtv") DO (
SET /A count=!count!+1
REM DETERMINE OUTPUT FILENAME
for /f "tokens=5,6,7,8,9,10 delims=\_" %%a in ("%%F") do (
set show=%%a
set station=%%b
set year=%%c
set month=%%d
set day=%%e
set hour=%%f
REM GENERATE OUTPUT NAMING CONVENTION
set output=!show! s!year!e!month!!day! !hour!
)
REM PROCESS WITH HANDBRAKE CLI
"C:\Program Files\Handbrake\HandBrakeCLI.exe" -i "%%F" -t 1 -c 1 -o %ripFolder%!OUTPUT!.mkv -f mkv --deinterlace="fast" --crop 58:60:2:2 --strict-anamorphic -e x264 -q 20 --vfr -a 1 -E faac -B 160 -6 dpl2 -R Auto -D 0 --gain=0 --audio-copy-mask none --audio-fallback ffac3 -x ref=1:weightp=1:subq=2:rc-lookahead=10:trellis=0:8x8dct=0 --verbose=1
REM MOVE CONVERTED FILE TO NAS
copy "%ripFolder%!OUTPUT!.mkv" "%putFolder%"
REM DELETE ORIGINAL
del "%%F"
REM DELETE LOCAL RIP
del "%ripFolder%!output!.mkv"
)
echo %count% files processed
pause
ENDLOCAL
As you have recognized, the exclamation mark is stripped before you can escape it.
That's because you expand the FOR-loop variable %%F while delayed expansion is enabled, and the exclamation mark tries to expand a variable.
You need to toggle the delayed expansion here, as the variable contents are safe when using with delayed expansion, but to get the value you need the disabled mode.
#echo off
setlocal DisableDelayedExpansion
SET count=0
FOR %%F IN ("%getFolder%*.wtv") DO (
set "orgFile=%%F"
SET /A count+=1
REM DETERMINE OUTPUT FILENAME
for /f "tokens=5,6,7,8,9,10 delims=\_" %%a in ("%%F") do (
set show=%%a
set station=%%b
set year=%%c
set month=%%d
set day=%%e
set hour=%%f
setlocal EnableDelayedExpansion
REM GENERATE OUTPUT NAMING CONVENTION
set output=!show! s!year!e!month!!day! !hour!
)
REM PROCESS WITH HANDBRAKE CLI
"C:\Program Files\Handbrake\HandBrakeCLI.exe" -i "%%F" -t 1 -c 1 -o %ripFolder%!OUTPUT!.mkv -f mkv --deinterlace="fast" --crop 58:60:2:2 --strict-anamorphic -e x264 -q 20 --vfr -a 1 -E faac -B 160 -6 dpl2 -R Auto -D 0 --gain=0 --audio-copy-mask none --audio-fallback ffac3 -x ref=1:weightp=1:subq=2:rc-lookahead=10:trellis=0:8x8dct=0 --verbose=1
REM MOVE CONVERTED FILE TO NAS
copy "%ripFolder%!OUTPUT!.mkv" "%putFolder%"
REM DELETE ORIGINAL
del "!orgFile!"
REM DELETE LOCAL RIP
del "%ripFolder%!output!.mkv"
endlocal
)

Resources