I wanted to make a batch file with multiple else conditions and already searched a lot but mine is not working. I want the file to check if two files exists and if they do then open one of that files. If one of the two files do not exist the batch should compare the next two files. My file looks like that:
IF EXIST "file1.txt" IF EXIST "file2.txt" Goto V1
IF EXIST "file3.txt" IF EXIST "file4.txt" Goto V2
IF EXIST "file5.txt" AND IF EXIST "file6.txt" Goto V3
:V1
cd "folder"
start sample.exe
goto commonexit
:V2
cd "folder2"
start sample2.exe
goto commonexit
:V3
cd "folder3"
start sample3.exe
goto commonexit
:commonexit
Like this the cmd opens and immediately closes. When I comment out the ":commonexit" it opens and works throug the code but it seems like in the double IF conditions (IF ... IF...) it only cares about the second IF. Putting an AND operator between them does not help.
Has anyone of you a guess, what could be wrong?
EDIT: the :commonexit is working. I just did not know that a breakline after :commonexit would make the code corrupt.
Here is one way:
#echo off
if exist "file1.txt" if exist "file2.txt" (
cd "folder"
start sample.exe
goto :EOF
)
if exist "file3.txt" if exist "file4.txt" (
cd "folder2"
start sample2.exe
goto :EOF
)
if exist "file5.txt" if exist "file6.txt" (
cd "folder3"
start sample3.exe
goto :EOF
)
Here is the logic:
file1 is checked for existence, if exist check if file2 exists, if it does, cd, execute sample and then goto end of file. If however file1 or file2 does not exist, it will skip the current code block and goto the next line of if's
Simpler and closer to the original code:
IF EXIST "file1.txt" IF EXIST "file2.txt" cd "folder" & start sample.exe & goto commonexit
IF EXIST "file3.txt" IF EXIST "file4.txt" cd "folder2" & start sample2.exe & goto commonexit
IF EXIST "file5.txt" IF EXIST "file6.txt" cd "folder3" & start sample3.exe & goto commonexit
rem Put here code that will execute when none of the previous paths execute...
:commonexit
EDIT: New method added
The new method below allows to write an efficient "AND" operation over several "EXIST filename" tests, and to chain several of these tests in a way similar to several "ELSE IF" commands:
(for /F "skip=1" %%a in ('dir /B file1.txt file2.txt') do break) && (
echo Both file1.txt and file2.txt exists
echo Process they here
) || (for /F "skip=1" %%a in ('dir /B file3.txt file4.txt') do break) && (
echo Both file3.txt and file4.txt exists
echo Process they here
) || (for /F "skip=1" %%a in ('dir /B file5.txt file6.txt') do break) && (
echo Both file5.txt and file6.txt exists
echo Process they here
) || echo Last else
This method is based on the "ExitCode" value returned by for /F command as explained at this answer (below Exit Code management section). The method can be easily extended to more files by just inserting the additional file names and adjusting the "skip=1" value to the number of files minus one. For example:
(for /F "skip=2" %%a in ('dir /B file1.txt file2.txt file3.txt') do break) && (
echo All file1.txt, file2.txt and file3.txt exists
echo Process they here
) || (for /F "skip=2" %%a in ('dir /B file4.txt file5.txt file6.txt') do break) && (
echo All file4.txt, file5.txt and file6.txt exists
echo Process they here
) || echo Last else
Here's an alternative one line solution, (split over 3 to maintain max 80 character line lengths), which uses the Where command:
(Where/Q "file1.txt"&&(Where/Q "file2.txt"&&Start /D "folder" "sample.exe"))||(
Where/Q "file3.txt"&&(Where/Q "file4.txt"&&Start /D "folder2" "sample2.exe"
))||Where/Q "file5.txt"&&Where/Q "file6.txt"&&Start /D "folder3" "sample3.exe"
Related
I have some pdf's in a folder that I need to organize them like this:
PDF name: 123.12.123.pdf ; 102030_01.pdf; 102030_02.pdf; 123.4512.34561.23412.pdf
Now I need to create folders with the filename (without the characters removed, ex: 12345123456123412) and rename them to the following pattern: ex: P12345123456123412_V1_A0V0_T07-54-369-664_S00001.pdf
for this I have used the following code which works very well:
#Echo Off
SetLocal EnableExtensions DisableDelayedExpansion
If "%~1" == "" GoTo :EOF
For %%G In (%*) Do (For %%H In ("%%~G") Do If "%%~aH" Lss "-" (
Echo Error! %%G no longer exists.
%SystemRoot%\System32\timeout.exe /T 2 /NoBreak 1>NUL
) Else If "%%~aH" GEq "d" (For %%I In ("%%~G\*.pdf") Do Call :Sub "%%~I"
) Else If /I "%%~xG" == ".pdf" (Call :Sub "%%~G"
) Else (Echo Error! %%G is not a PDF
%SystemRoot%\System32\timeout.exe /T 2 /NoBreak 1>NUL))
GoTo :EOF
:Sub
Set "basename=%~n1"
Set "basename=%basename:.=%"
MD "%~dp1%~n1" 2>NUL
If Not ErrorLevel 1 Move /Y %1 "%~dp1%~n1\P%basename:-=%_V1_A0V0_T07-54-369-664_S00001_Volume%~x1"
Exit /B
I drag the pdfs into the .bat and it does the adjustment.
It happens that there is a case that I am not able to handle. Some pdfs need to be in the same folder, for example in the following case:
PDF name: 102030_01.pdf; 102030_02.pdf;
Note that the pdfs have the same number, only after the _ that we have the difference. In this case you would need to create a folder with the name:102030
And move the two files into it, modifying their name as follows:
102030_01.pdf -> P102030_V1_A0V0_T07-54-369-664_S00001.pdf
102030_02.pdf -> P102030_V1_A0V0_T07-54-369-664_S00002.pdf
Could anyone help?
:Sub
Set "basename=%~n1"
Set "basename=%basename:.=%"
if /i "%basename%" neq "%basename:_=%" goto sub2
MD "%~dp1%~n1" 2>NUL
If Not ErrorLevel 1 Move /Y %1 "%~dp1%~n1\P%basename:-=%_V1_A0V0_T07-54-369-664_S00001_Volume%~x1"
Exit /B
:sub2
for /f "tokens=1*delims=_" %%b in ("%basename%") do (
MD "%~dp1%%b" 2>NUL
ECHO Move /Y %1 "%~dp1%%b\P%basename:-=%_V1_A0V0_T07-54-369-664_S000%%c_Volume%~x1"
)
Exit /B
Always test on dummy data first.
This code echoes the proposed move. After verification, remove the echo keyword to activate.
Caution: My reading of the code is that - should be removed from the basename in the new name, and that _Volume should be appended to the name part, which is not shown in your examples.
Essentially, if the basename contains _ then goto sub2.
sub2 partitions the name in basename, assigning the first part to %%b and the second to %%c (See for /? from the prompt for documentation)
Then the directory is created
The md will object if the directory already exists, hence the 2>nul in the original code (suppresses error messages)
If md found that error in the original then this appears to be a problem, so the move is not executed. In the new version, it is expected that the directory may already exist, so the errorlevel processing has been removed.
This part of my script is supposed to go through directories looking for *.wim files and if it finds them on the "images" folder, proceed. However, it is going straight to the "else" part of the code :/
ECHO. Checking for WIMs
ECHO ............................................
ECHO.
for /F "tokens=*" %%f in ('dir /B /S "%w%:\data\images"') do (
if exist "%%~ff\*.wim" (
ECHO found me some wims! let's continue.
GOTO actionmenu
) else (
ECHO This script requires a wim repository folder to proceed. make sure you have
ECHO properly populated the "\Images" folder before re-running this script
goto end
)
)
You don't even need a for loop. Dir gives an %errorlevel% of 1, if it doesn't find something:
dir /B /S "%w%:\data\images\*.wim" >nul && (
echo found at least one wim file.
) || (
echo no wim files found.
)
&& works as "if previous command was successful (dir found at least one file), then"
|| is the opposite: " if previous command failed (dir didn't find a matching file) then"
for /F "tokens=*" %%f in ('dir /B /S /AD "%w%:\data\images"') do (
if exist "%%f\*.wim" (
ECHO found me some wims! let's continue.
GOTO actionmenu
) else (
ECHO This script requires a wim repository folder to proceed. make sure you have
ECHO properly populated the "\Images" folder before re-running this script
goto end
)
)
hope you can help me with this, i can't make it work what i need
I need to copy all the .pdf files from a source folder, create a folder with part of the name "T-123456" and add the respective PDF files found in the correct folder in the destination folder, but sometimes the name it varies or the reference change "SM17-123".
Example of files
HC002T-1234562436787004332
MV002T-1234562436787004332
PP _002_T-123456_24_3678_7004332
Types of direfents files
HC123CLG-32-172436787004259
HC123SM17-1802436787004044
i have this code created but it makes part of the job because the name varies and create folders incorrect for that files, sometimes the files have more digits in the beggining example 001 or 0001, so i dont know how to omit the other references files and only work whith files "T-123456" also i need the batch continuously working for new files created in the source folder and if i have another routhe where i have other types of file and copy to the correct reference it would be great.
#echo off
title Electronic File
:loop
cls
timeout -t 1 >nul
color b
for %%A in (*.pdf) do (
echo File Found %%A
for /f "delims=" %%B in ("%%A") do set fname=%%~nB
for /f "delims=" %%C in ("%%A") do set fextn=%%~xC
for /f "tokens=1* delims=" %%D in ("!fname:~5,8!") do set folname=%%D
echo Name folder !folname!
if not exist "!folname!" (
echo Folder !folname! dont exist, creating
md "!folname!" 2>nul
) else (
echo Folder !folname! exists
)
echo Copying file %%A to folder !folname!
xcopy "%%A" "!folname!"
)
echo on
md "C:\test %All%"
xcopy /s /y "X:\test\pdf" "W:\Electronic File %All%"
goto :loop
pause
for %%A in (*.pdf) do (
echo File Found %%A
set fname=%%~nA
set fextn=%%~xA
set folname=!fname:~5,8!
ECHO !folname!|FINDSTR /i /r "[A-Z]-[0-9][0-9][0-9][0-9][0-9][0-9]" >NUL
IF ERRORLEVEL 1 (
ECHO %%A - !folname! excluded
) ELSE (
echo Name folder !folname!
if not exist "!folname!" (
echo Folder !folname! dont exist, creating
ECHO md "!folname!" 2>nul
) else (
echo Folder !folname! exists
)
echo Copying file %%A to folder !folname!
ECHO xcopy "%%A" "!folname!"
)
)
Here's the meat of the matter. delayedexpansion needs to be on - you don't show that in your original code.
Note that there is no requirement for %%B, %%C, %%D as within the loop, %%A contains the filename and hence you can set the variables from that name.
Note that fextn will apparently always be .pdf since that is the extension you specify in your filemask *.pdf so setting it seems superfluous.
The syntax SET "var=value" (where value may be empty) may be used to ensure that any stray trailing spaces are NOT included in the value assigned.
The change I've introduced is to echo the directoryname to findstr, searching /i case-insensitively for /r a regular-expression which is one letter, a dash and then 6 numerics. If the directoryname matches then errorlevel will be set to 0 by findstr, otherwise, it will be set to 1.
The if errorlevel 1 means "if errorlevel is 1 or greater" and if that is so, the match was UNsuccessful, so report the filename and extracted directoryname; otherwise, go through your logic (I've changed it to simply echo the md and xcopy commands, for testing).
Given that we now have a variable structure,
for %%A in (*.pdf) do (
echo File Found %%A
set "copied="
set fname=%%~nA
set fextn=%%~xA
set folname=!fname:~5,8!
ECHO !folname!|FINDSTR /i /r "[A-Z]-[0-9][0-9][0-9][0-9][0-9][0-9]" >NUL
IF not ERRORLEVEL 1 call :process "%%A"
rem repeat this section for each match required - begin
if not defined copied (
set folname=!fname:~5,9!
ECHO !folname!|FINDSTR /i /r "[A-Z][A-Z][A-Z]-[0-9][0-9]-[0-9][0-9]" >NUL
IF not ERRORLEVEL 1 call :process "%%A"
)
rem repeat this section for each match required - end
if not defined copied ECHO %%A - !folname! excluded
)
goto :eof
:process
echo Name folder %folname%
if not exist "%folname%" (
echo Folder %folname% dont exist, creating
ECHO md "%folname%" 2>nul
) else (
echo Folder %folname% exists
)
echo Copying file %~1 to folder %folname%
ECHO xcopy "%~1" "%folname%"
set "copied=Y"
goto :eof
In your extended examples, it's not clear where the PP fits into the scheme.
The formula is reasonably simple. The start position is the first argument in the set (counting from first character=0) and the second the length to select. The regex match may be either a single character (matched literally) or [rangestart-rangeend] . matches any one character, so the first block I've shown selects from HC123CLG-32-172436787004259 from the 5th character (starting at 0) for 9 characters =CLG-32-17 and matches this against alpha,alpha,alpha,-,numeric,numeric,-,numeric,numeric.
On a match, errorlevel is set to 0, so the :process subroutine is called, with a parameter of %%A in quotes. The subroutine uses the value in folname and copies the file (name now in %1 - %~1 removes the quotes) as before.
So - it's as simple as repeating the block of code, altering the start and length of the string to be selected and changing the regex to suit the required pattern.
Is it possible to make a batch file that will rename a folder if does not have a specific name?
EG:
Parent Directory
- - - > info
- - - > randomfoldername
I have many folders that follow the above pattern. What I would like to do is make a batch file that will rename "randomfoldername" in this structure. There is always two folders in the Parent Directory, one is always "info" and the other changes for each case. Is there a method within a batch file that I could use to always rename the "randomfoldername" directory? I was thinking something along the lines of,
IF NOT == "info" THEN ren... ect.
Is this possible?
you can first check if folder exist then rename folder
if not exist c:\info ( call random.bat )
random.bat:
dir /A:D /b | findstr.exe /n /R "." > s:\sites\file-count.txt
FOR /F "tokens=1-10 delims=:" %%A IN ('type "s:\sites\file-count.txt"') do
set NUMBER-OF-FILES=%%A
FOR /L %%A IN (1,1,%number-of-files%) DO CALL RENAME.bat %%A
rename.bat
:rename
FOR /F "tokens=1-10 delims=:" %%A IN ('type "s:\sites\file-count.txt" ^|
findstr "%1:"') do ren %%B %RANDOM%%%B
also u can use free tool like Bulk Rename Utility
that app has cli for use in bat file here
also You can use powershell script like
$a = test-path c:\info
if ( $a -eq "True" ) { Write-Host nothing to do } Else { gic -directory path | %{$n="$pwd\$((get-random).tostring())$($_.name)";$_.moveto($N)} }
Next script starts with basic checks on command line parameter passed into.
FOR /F loop against the results of another command (dir) used. Next explanation stolen (see dbenham's original) :
FOR /R (as well as the simple FOR) begin iterating immediately, before
it has finished scanning the disk drive. It is possible for the loop
to reiterate the already named file! This would cause it to be renamed
twice, giving the wrong result. The solution is to use FOR /F with
command 'DIR /B', because FOR /F always processes the command to
completion before iterating.
#ECHO OFF >NUL
SETLOCAL enableextensions disabledelayedexpansion
set "ParentDirectory=%*"
if "%ParentDirectory%"=="" goto :usage1
if not exist "%ParentDirectory%\" goto :usage2
if not exist "%ParentDirectory%\info\" goto :usage3
set "SpecificName=Desired Name"
set /A "count=0"
for /F "delims=" %%G in ('dir /B /A:D "%ParentDirectory%\"') do set /A "count+=1"
if %count% neq 2 goto :usage4
for /F "delims=" %%G in ('dir /B /A:D "%ParentDirectory%\"') do (
if /I not "%%~G"=="info" (
if /I not "%%~G"=="%SpecificName%" (
echo renaming "%ParentDirectory%\%%~G" to "%SpecificName%"
rename "%ParentDirectory%\%%~G" "%SpecificName%"
) else (
echo renamed already: "%SpecificName%"
)
)
)
:endlocal
ENDLOCAL
goto :eof
:usage1
echo no paramater
goto :endlocal
:usage2
echo "%ParentDirectory%" folder does not exist
goto :endlocal
:usage3
echo "%ParentDirectory%\info" folder does not exist
goto :endlocal
:usage4
echo "%ParentDirectory%" folder contains %count% subfolders
goto :endlocal
Output:
==>29376745.bat
no paramater
==>29376745.bat x y
"x y" folder does not exist
==>29376745.bat d:\test
"d:\test\info" folder does not exist
==>md "d:\test\info"
==>29376745.bat d:\test
"d:\test" folder contains 6 subfolders
==>29376745.bat d:\test\29376745
renaming "d:\test\29376745\currentName" to "Desired Name"
==>29376745.bat d:\test\29376745
renamed already: "Desired Name"
==>
Required reading (indexes only):
An A-Z Index of the Windows CMD command line
Windows CMD Shell Command Line Syntax
Thanks to foxidrive I have this code:
batch to copy in clipbrd filenameandpath of the older file in folderA except the same name in folderB
#echo off
:loop
set "d="
set "done="
set /p "d=Type source path (or press enter for current folder): "
if not defined d set "d=%cd%"
if not exist "%d%" echo Enter valid path - try again & goto :loop
cd /d "%d%"
for /f "delims=" %%a in ('dir *.mxf /b /od /a-d') do (
if defined done goto :EOF
if not exist "d:\folderB\%%~na.*" (
echo %%~fa|clip >nul
set done=1
)
)
OK, it work very well, thanks!
now I should like to do this:
and then the batch have to nename a file o:\temp.avi with the filename choosed by the batch (and putted into the clipbrd) example: if the batch have choose (into folderA) C0001.mxf, it have to rename o:\temp.avi --------> C0001.avi
Add the line in the middle between the other two.
echo %%~fa|clip >nul
ren "o:\temp.avi" "%%~nxa.avi"
set done=1
Read the help section on how Stack Overflow works: https://stackoverflow.com/tour