Batch file finding a filename which contains a substring - batch-file

I want to write a batch file to find all .vsdm files and the file name must contain a substring "2.4". But my code is telling me that all my .vsdm files contains the substring "2.4" which is not correct.
FOR /R %completepath% %%G IN (*.vsdm) DO (
set file=%%~nG
If not "%file%"=="%file:2.4=%" (
echo Filename contains 2.4
) else (
echo Filename does NOT contains 2.4
)
)
Can anyone tell me where did I get it wrong?Thanks

If "%file%"=="%file:2.4=%" (
echo Filename "%file%" does NOT contain 2.4
) else (
echo Filename "%file%" contains 2.4
)
Including the filename in the echo may reveal more. I can see no reason for the double-negative approach. The way the code operates may depend on precisely where in code the instructions are located, for instance if these lines are contained within any variety of loop or code-block, operation may depend on other elements, so it's important to present the code in-context and with an example of what was expected and what actually happened.
correct fomatting makes all clear.
There are one or two SO articles about delayed expansion which OP should become familiar with.
SETLOCAL ENABLEDELAYEDEXPANSION
FOR /R %completepath% %%G IN (*.vsdm) DO (
set "file=%%~nG"
If not "!file!"=="!file:2.4=!" (
echo Filename contains 2.4
) else (
echo Filename does NOT contains 2.4
)
)
ENDLOCAL

You can use the command Where /? that let you use wildcard characters ( ? * ) and UNC paths.
#echo off
Title Find the location of a file with substring by Hackoo
Color 0A
Call :inputbox "Enter the file name to search :" "Enter the file name to search"
If "%input%" == "" Color 0C & (
echo(
echo You must enter a filename to continue with this program
pause>nul & exit
) else (
Call :Browse4Folder "Select the source folder to scan %input%" "c:\scripts"
)
Set "ROOT=%Location%"
::We check whether the input string has an anti-Slach in the end or no ? if yes, we remove it !
IF %ROOT:~-1%==\ SET ROOT=%ROOT:~0,-1%
set whereCmd=where.exe /r %ROOT% %input%
for /f %%a in ('%whereCmd%') do echo %%~nxa --^> %%a
pause & exit
::***************************************************************************
:Browse4Folder
set Location=
set vbs="%temp%\_.vbs"
set cmd="%temp%\_.cmd"
for %%f in (%vbs% %cmd%) do if exist %%f del %%f
for %%g in ("vbs cmd") do if defined %%g set %%g=
(
echo set shell=WScript.CreateObject("Shell.Application"^)
echo set f=shell.BrowseForFolder(0,"%~1",0,"%~2"^)
echo if typename(f^)="Nothing" Then
echo wscript.echo "set Location=Dialog Cancelled"
echo WScript.Quit(1^)
echo end if
echo set fs=f.Items(^):set fi=fs.Item(^)
echo p=fi.Path:wscript.echo "set Location=" ^& p
)>%vbs%
cscript //nologo %vbs% > %cmd%
for /f "delims=" %%a in (%cmd%) do %%a
for %%f in (%vbs% %cmd%) do if exist %%f del /f /q %%f
for %%g in ("vbs cmd") do if defined %%g set %%g=
goto :eof
::***************************************************************************
:InputBox
set "input="
set "heading=%~2"
set "message=%~1"
echo wscript.echo inputbox(WScript.Arguments(0),WScript.Arguments(1)) >"%temp%\input.vbs"
for /f "tokens=* delims=" %%a in ('cscript //nologo "%temp%\input.vbs" "%message%" "%heading%"') do (
set "input=%%a"
)
exit /b
::***************************************************************************

Related

How do I substring a dynamic variable value in windows batch scripting

Not able to substring the dynamic variable inside forloop in Windows batch script.
I have the properties file in my git hub in the below format.
"collectionName=TestCollectionRun.json=test"
So I have written the below code to fetch this values.But the requirement is that I need to strip of the '.json' part from collection name.With the below code I am not able to set/echo that value.Can you please help on this!
#ECHO ON
:BEGIN
IF EXIST "test.properties" ECHO Found properties file, reading file..
SET props=test.properties
setlocal EnableDelayedExpansion
For /F "delims== tokens=1,2,3" %%G in (%props%) Do (
if "%%I" EQU "test" if "%%G" EQU "collectionName" SET collName=%%H(
SET finalCollName=%collName%:~0,-5
ECHO %finalCollName%
)
)
:END
We need the ECHO to return "TestCollectionRun".currently its not returning anything.
For /F "delims== tokens=1,2,3" %%G in (%props%) Do (
if "%%I" EQU "test" if "%%G" EQU "collectionName" SET "collName=%%~nH"&echo %%~nH
)
ECHO %CollName%
Note the second ) is now redundant. Your problem has to do with delayedexpansion which you are invoking but not using. call %%collname%% within the for loop would have shown the value after assignment if required.
This code works by interpreting %%H as a filename and assigning simply the name part of %%H (%%~nH)
Given a line content of collectionName=TestCollectionRun.json=test, here's a quick rewrite of what I think you're tring to do:
#Echo Off
Set "props=test.properties"
If Not Exist "%props%" (
Echo Properties file not found!
Echo Exiting..
Timeout /T 3 /NoBreak >NUL
Exit /B
)
Echo Found properties file, reading file..
For /F "UseBackQ Tokens=1-3 Delims==" %%A In ("%props%") Do (
If /I "%%C" == "test" If /I "%%A" == "collectionName" Echo %%~nB
)
Pause
If you wanted to do something with the collection name within the loop then you would probably need to use delayed expansion:
#Echo Off
SetLocal DisableDelayedExpansion
Set "props=test.properties"
If Not Exist "%props%" (
Echo Properties file not found!
Echo Exiting..
Timeout /T 3 /NoBreak >NUL
Exit /B
)
Echo Found properties file, reading file..
For /F "UseBackQ Tokens=1-3 Delims==" %%A In ("%props%") Do (
If /I "%%C" == "test" If /I "%%A" == "collectionName" (
Set "collName=%%B"
SetLocalEnableDelayedExpansion
Echo !collName!
Rem Perform substring task on the variable named collName
Set "finalCollName=!collName%:~0,-5!"
Echo !finalCollName!
EndLocal
)
)
Pause
Note, these answers will not work, as is, if your string is surrounded by doublequotes, (as in your question body), or if the line content differs (e.g. begins with spaces or tabs).
[Edit /]
Looking at your 'after the fact' question in the comments, it is clear that you do not need to substring the variable at all, so should use the first method posted:
Echo Found properties file, reading file..
For /F "UseBackQ Tokens=1-3 Delims==" %%A In ("%props%") Do (
If /I "%%C" == "test" If /I "%%A" == "collectionName" (
newman run "%%B" -e "%envName%" --insecure --reporters cli,htmlextra --reporter-htmlextra-export "newman\%BUILD_NUMBER%\%%~nB.html" --disable-unicode
)
)
Pause
This assumes that both %envName% and %BUILD_NUMBER% have been previously defined correctly.

Speed up batch code

Can you advice what else I can do for speeding up my batch, please?
Works quite well apart takes ages to finish :)
Sorry for this text but I'm not able to post my question due to the message 'it looks like your post is mostly code bla bla bla. Admin- can you turn this verification OFF!!!
#echo off
c:
cd \
pushd \\ftp\ftp$
cls
echo ________________________________________________________________
echo.
color f9
:WPIS
set /p moje=Please enter required LOGIN NAME:
if exist "\\ftp\ftp\Transfer\%moje%" echo USER ALREADY EXIST TRY ANOTHER ONE && GOTO WPIS
:KOD
set mojep=%random%%random%%random%
setlocal enabledelayedexpansion
set input=default2015.Archive
set output2=%moje%.Archive2
set output1=%moje%.Archive1
set output=%moje%.Archive
set text2searchfor=default2015
set password2searchfor=szukajpassword
set folder2search=F:\\Transfer\\default2015
set newfolder=F:\\Transfer\\%moje%
del %output1%
cls
echo Wait....
for /F "tokens=*" %%f in ('type %input%') do (
set line=%%f
if "!line!"=="%text2searchfor%" (
set NAME=%moje%
echo !NAME!>> %output2%
) else (
echo !line!>> %output2%
)
)
for /F "tokens=*" %%f in ('type %output2%') do (
set line=%%f
if "!line!"=="%folder2search%" (
set NAME=%newfolder%
echo !NAME!>> %output1%
) else (
echo !line!>> %output1%
)
)
for /F "tokens=*" %%f in ('type %output1%') do (
set line=%%f
if "!line!"=="%password2searchfor%" (
set NAME=%mojep%
echo !NAME!>> %output%
) else (
echo !line!>> %output%
)
)
del %output1%
del %output2%
pushd \\ftp\ftp\Transfer\
md %moje%
popd \\ftp\ftp\Transfer\
popd \\ftp\ftp$
...
Try this:
#echo off
c:
cd \
pushd \\ftp\ftp$
cls
echo ________________________________________________________________
echo.
color f9
:WPIS
set /p moje=Please enter required LOGIN NAME:
if exist "\\ftp\ftp\Transfer\%moje%" echo USER ALREADY EXIST TRY ANOTHER ONE && GOTO WPIS
:KOD
set mojep=%random%%random%%random%
setlocal
set input=default2015.Archive
set output2=%moje%.Archive2
set output1=%moje%.Archive1
set output=%moje%.Archive
set text2searchfor=default2015
set password2searchfor=szukajpassword
set folder2search=F:\\Transfer\\default2015
set newfolder=F:\\Transfer\\%moje%
cls
echo Wait....
(for /F "delims=" %%f in (%input%) do (
if "%%f"=="%text2searchfor%" (
echo %moje%
) else (
echo %%f
)
)) > %output2%
(for /F "delims=" %%f in (%output2%) do (
if "%%f"=="%folder2search%" (
echo %newfolder%
) else (
echo %%f
)
)) > %output1%
(for /F "delims=" %%f in (%output1%) do (
if "%%f"=="%password2searchfor%" (
echo %mojep%
) else (
echo %%f
)
)) > %output%
del %output1%
del %output2%
pushd \\ftp\ftp\Transfer\
md %moje%
popd \\ftp\ftp\Transfer\
popd \\ftp\ftp$
If more speed is needed, a much faster solution may be written via a Batch-JScript hybrid script.
This uses a native Windows batch script called Jrepl.bat (by dbenham)
- download from: https://www.dropbox.com/s/4otci4d4s8x5ni4/Jrepl.bat
and it can also be found here: http://www.dostips.com/forum/viewtopic.php?f=3&t=6044
It is significantly faster for large files than plain vanilla for loops.
This assumes that your strings to be replaced are not embedded in any other lines, and just occur by themselves.
As you are changing the directory, placing jrepl.bat on the system path is wise so the script can find it, or hard code the path to jrepl.bat
#echo off
cd /d c:\
pushd \\ftp\ftp$
cls
echo ________________________________________________________________
echo.
color f9
:WPIS
set /p moje=Please enter required LOGIN NAME:
if exist "\\ftp\ftp\Transfer\%moje%" echo USER ALREADY EXIST TRY ANOTHER ONE && GOTO WPIS
:KOD
set mojep=%random%%random%%random%
setlocal enabledelayedexpansion
set input=default2015.Archive
set output2=%moje%.Archive2
set output1=%moje%.Archive1
set output=%moje%.Archive
set text2searchfor=default2015
set password2searchfor=szukajpassword
set folder2search=F:\\Transfer\\default2015
set newfolder=F:\\Transfer\\%moje%
cls
echo Wait....
call jrepl "%text2searchfor%" "%moje%" /L /f %input% /o %output%
call jrepl "%folder2search%" "%newfolder%" /L /f %output% /o -
call jrepl "%password2searchfor%" "%mojep%" /L /f %output% /o -
pushd \\ftp\ftp\Transfer\
md %moje%
popd \\ftp\ftp\Transfer\
popd \\ftp\ftp$

Only use first word of input batch file

I am making a program that needs to run the commands that users put in.
If the command doesn't exist it opens an error.
:cmd
set /p cmd="Command:"
if not exist %cmd% goto nocommand
%cmd%
:noCommand
echo Error, command doesn't exist..
goto cmd
But if I type "echo text" it says text isn't a command. I need it to only read the first word.
Checks if its is possible to execute the command as an internal,from given path or from %PATH%. It uses also solution from dbenham from here : Check if command is internal in CMD
#echo off
:cmd
set /p "cmd=Command:"
for /f "tokens=1 delims= " %%a in ("%cmd%") do set "fcmd=%%~na"
setlocal
set "empty=%temp%\empty%random%"
md "%empty%"
pushd "%empty%"
set path=
>nul 2>nul %fcmd% /?
if not errorlevel 9009 (
popd
rd "%empty%"
echo %fcmd% is internal command
endlocal
goto :execute
) else (
popd
rd "%empty%"
endlocal
)
color
for %%# in (%PATHEXT%;"" ) do (
rem echo --%fcmd%%%~#--
if exist %fcmd%%%~# (
echo the command/executable/script will be executed from given location
goto :execute
)
for /f "tokens=1 delims= " %%a in ("%fcmd%%%~#") do (
if "%%~$PATH:a" NEQ "" (
echo the command/executable/script is defined in %%PATH%%
rem
goto :execute
)
)
)
echo command does not exist
exit /b 1
:execute
%cmd%
set /p cmd="Command:"
for /f "tokens=1" %%i in ("%cmd%") do set firstword=%%i
echo %firstword%

If conditional in batch (inside a for, inside an if)

I have an application that reads through all the files in the directory and will rename those files (if necessary) and create log files from the innards of them, however there are a couple of catches....
If the files 15th character is something other than a "." or "_", substring the 14 characters previous plus the 15th and store as variable.
If the files 15th character is a "." or "_" substring the 14 characters previous and store as variable.
For example, if filename is: DIY_0000000000a.xml the variable would be DIY_0000000000a and if the filename is: DIY_0000000000.xml the variable would be DIY_0000000000
There is a catch to all of this...
If the user picks Option 2, which is to rerun the application, then the application should rename all files in the directory to DIY_xxx_rerun.xml or DIY_xxxa_rerun.xml (should now explain the "_" in the aforementioned options.
The problem I have and what I need assistance with is that I can't seem to get the conditional logic correct. The application works, but if I have a mix of files in the directory (ie: DIY_0000000000a.xml, DIY_0000000000.xml & DIY_0000000000_rerun.xml, DIY_0000000000a_rerun.xml) it may work on one kind but not the other. Help is much appreciated.
Below is a snippet of my current code:
SETLOCAL EnableDelayedExpansion
:EXECUTE
::IF AN XML FILE EXISTS ADD IT TO A LOG FILE, PROMPT USER IF THEY WANT TO VIEW IT
ECHO.
ECHO =============================================
ECHO **SELECT YOUR OPTION BY USING YOUR KEYBOARD**
ECHO =============================================
ECHO.
ECHO 1 - Generate DIY Log Files for normal orders
ECHO 2 - Generate DIY Log Files for _rerun orders
ECHO 3 - EXIT
ECHO.
ECHO.
SET /P CHOICE=Type your option, then press ENTER:
IF %CHOICE%==1 (
SET RERUN=
GOTO PROCESS
)
IF %CHOICE%==2 (
SET RERUN=_rerun
GOTO PROCESS
)
IF %CHOICE%==3 EXIT
IF NOT '%CHOICE%'== SET CHOICE=%CHOICE:~0,1%
ECHO.
ECHO "%CHOICE%" is not a valid option.
PAUSE
GOTO EXECUTE
:PROCESS
IF EXIST DIY*.xml (
SET /a FILECOUNTER=0
ECHO.
ECHO Processing...
FOR /f "delims=" %%a IN ('DIR /b /a-d /on DIY*.xml') DO (
SET /a LOGCOUNTER=!FILECOUNTER!/1+1
SET ORDERNUMBER=%%a
IF "!ORDERNUMBER:~14,1!" NEQ "." (
IF "!ORDERNUMBER:~14,1!" NEQ "_" (
SET ORDERNUMBSTR=!ORDERNUMBER:~0,15!
) ELSE (
SET ORDERNUMBSTR=!ORDERNUMBER:~0,14!
)
)
SET ORDERNUMBSTR=!ORDERNUMBER:~0,14!
IF "%RERUN%"=="_rerun" (
REN !ORDERNUMBSTR!.xml !ORDERNUMBSTR!%RERUN%.xml >NUL 2>&1
) ELSE (
REN *!ORDERNUMBSTR!*.xml !ORDERNUMBSTR!.xml >NUL 2>&1
)
FOR /f "tokens=4 delims=<>" %%i IN ('TYPE !ORDERNUMBSTR!%RERUN%.xml ^|find "DIY_LOG_ID"') DO (
SET DIYLOGID=%%i
)
FOR /f "tokens=7 delims=<>" %%j IN ('TYPE !ORDERNUMBSTR!%RERUN%.xml ^|find "ACCOUNT_KEY"') DO (
SET ACCOUNTKEY=%%j
FOR /f "tokens=1-3 delims=-" %%x IN ("!ACCOUNTKEY!") DO (
SET CONTRACTNR=%%x
SET PLANSEQ=%%y
SET SUBSEQ=%%z
)
)
...
ENDLOCAL
Just needed a day to think about it...
Was able to get what I wanted by using the following FOR loop instead of IFs
FOR /f "delims=" %%a IN ('DIR /b /a-d /on DTL*.XML') DO (
SET /a LOGCOUNTER=!FILECOUNTER!/1+1
SET ORDERNUMBER=%%a
**FOR /f "tokens=1,2 delims=_." %%p IN ("!ORDERNUMBER!") DO (
SET ORDERNUMBSTR=%%p_%%q**
)
IF "%RERUN%"=="_rerun" (
REN !ORDERNUMBSTR!.XML !ORDERNUMBSTR!%RERUN%.XML >NUL 2>&1
) ELSE (
REN *!ORDERNUMBSTR!*.XML !ORDERNUMBSTR!.XML >NUL 2>&1
)
...

Findstr doesn't accept variable CMD

The purpose is to scan a given folder for media files and send the mediainfo to info.txt BUT also to give user an option to scan only for files having a particular text string.
My bat file:
#echo off
setLocal EnableDelayedExpansion
echo. >info.txt
set /P "folder=Enter folder path: "
set /P "_input=Search all files (y/n): "
if /I "%_input%" == "y" (
dir %folder% /B /O:N | findstr /I ".wmv$ .mpg$ .mkv$ .mpeg$ .mp4$ .avi$" >filename.txt
for /f "tokens=* delims= " %%a in ('type filename.txt') do (
set _in=%_in%%%a
mediainfo --Inform=file://template.txt "%folder%!_in!" >>info.txt
echo. >>info.txt
)
) else (
set /P "_str=Enter file string: "
dir %folder% /B /O:N | findstr /I "%_str%" >filename.txt
for /f "tokens=* delims= " %%a in ('type filename.txt') do (
set in=%in%%%a
mediainfo --Inform=file://template.txt "%folder%!in!" >>info.txt
echo. >>info.txt
)
)
del filename.txt
cls
pause
Though the first part of if loop works correctly but the 'else' part don't, I can't get the error because with a flicker of an eye it disappears & I can't troubleshoot it
Well you could troubleshoot if you left ECHO ON and removed the CLS or put the pause before CLS.
Your ELSE block is failing because you are setting _str within the block and then attempting to use the value via normal expansion. You need to use delayed expansion.
Even your first IF block looks wrong because your SET statement is using normal expansion. The end result is each iteration is simply passing the current filename to mediainfo, which actually makes sense. It looks to me like you don't even need the _in variable in either block.
Your code is way more complicated than need be: I believe the following will give the result you are looking for:
#echo off
setlocal
echo. >info.txt
set /P "folder=Enter folder path: "
set /P "_input=Search all files (y/n): "
if /i "_input" == "y" (
set "_mask=*.wmv *.mpg *.mkv *.mpeg *.mp4 *.avi"
) else (
set /P "_mask=Enter file string: "
)
if /i "_input" neq "y" set "_mask=*%_mask%*"
pushd "%folder%"
set "popped="
for %%F in (%_mask%) do (
if not defined popped popd
set popped=1
mediainfo --Inform=file://template.txt "%%F" >>info.txt
echo. >>info.txt
)
pause
I would take it one step further and expect the user to supply any wildcards in the file string. That would give the user more control, and would simplify the code a bit more.
#echo off
setlocal
echo. >info.txt
set /P "folder=Enter folder path: "
set /P "_input=Search all files (y/n): "
if /i "_input" == "y" (
set "_mask=*.wmv *.mpg *.mkv *.mpeg *.mp4 *.avi"
) else (
set /P "_mask=Enter file mask: "
)
pushd "%folder%"
set "popped="
for %%F in (%_mask%) do (
if not defined popped popd
set popped=1
mediainfo --Inform=file://template.txt "%%F" >>info.txt
echo. >>info.txt
)
pause

Resources