Dynamic for set in batches - list

I want 2 types of lists
The first list with types for example daily and release and the second type with paths for the first list.
After that I want dynamicly go through the second type lists based on the first type list.
Something like that:
#ECHO OFF
REM ##########
REM ## Test ##
REM ##########
SETLOCAL EnableDelayedExpansion
SET VersionType=(Daily Release)
SET TagetsDaily=(path1 path2)
SET TagetsRelease=(path23 path24)
FOR %%n IN %VersionType% DO (
ECHO !Tagets%%n!
SET test_temp=!Tagets%%n!
ECHO %test_temp%
FOR %%i !Tagets%%n! DO (
ECHO %%i
)
)
PAUSE
EXIT
The problem of this code is that it doesn't worked.
OUTPUT:
"!Tagets%n!" can be syntactically processed at this point.
And with out the secound for its:
(path1 path2)
ECHO is off (OFF).
(path23 path24)
ECHO is off (OFF).
Can me anyone explain me why thats is a syntactic error and why I can copy the content from !Tagets%%n! into an other variable??

try this:
#ECHO OFF &SETLOCAL ENABLEDELAYEDEXPANSION
SET "VersionType=Daily Release"
SET "TagetsDaily=path1 path2"
SET "TagetsRelease=path23 path24"
FOR %%n IN (%VersionType%) DO (
ECHO !Tagets%%n!
SET test_temp=!Tagets%%n!
ECHO !test_temp!
FOR %%i IN (!Tagets%%n!) DO (
ECHO %%i
)
)
Please look at for /? and delayed expansion.

Related

Problem with variables and if statement within a for loop in a batch script

been working in this batch code for a couple of days and I cannot make it work right.
To give you a perspective, this code is intended to read a file that contains some "selected" numbers which refer to other files contained in another folder. These files contain a lot of data arranged by rows and columns. The first rows are not important so the code is skipping 50 rows to save time, then I am interested in the 2nd and 7th columns so these are exported to variables (A,B) for each row. If there is a combination of values between these two variables (e.g. A>1000 & B>0.03) on the same row the code is supposed to export the file number where this happened.
Problem: the IFs that compare these columns don't work as expected, the GTR/GEQ don't seem to respect the "more than" and the code exports file numbers even when there is no such combination in the file.
I have tried two codes so far:
Code 1
#echo off
setlocal EnableDelayedExpansion
for /f "tokens=*" %%s in (selected.txt) do (
cd %~dp0\Melts\MeltNPTdis-8-%%s
for /f "skip=50 tokens=2,7 delims= " %%A in (file.txt) do (
if %%A GTR 1000 if %%B GTR 0.03 (
cd %~dp0
>>dummy.txt echo %%s
)))
Code 2, with check variables
#echo off
setlocal EnableDelayedExpansion
for /f "tokens=*" %%s in (selected.txt) do (
cd %~dp0\Melts\MeltNPTdis-8-%%s
for /f "skip=50 tokens=2,7 delims= " %%A in (file.txt) do (
set /a x=0
set /a y=0
if %%A GTR 999 (
set /a x=1
)
if %%B GTR 0.03 (
set /a y=1
)
set /a z= !x! + !y!
if !z! EQU 2 (
cd %~dp0
>>dummy.txt echo %%s
)))
Can someone light me up on this one? I have isolated the problem to the IFs and have tried to define the variables differently like %%A or %%A%% not solving the issue.
Thanks a lot!
You would need to test both sides of the fractional numbers as cmd can only work with 32bit integers. You could however get a little help from powershell to overcome this. Note this is untested as I am on my mobile device and obviously do not have the environment you have to test:
#echo off
for /f "usebackq delims=" %%s in ("selected.txt") do (
(for /f "usebackq skip=50 tokens=2,7 delims= " %%A in ("%~dp0Melts\MeltNPTdis-8-%%s\file.txt") do powershell "if (%%A -gt 0.04) {if (%%A -gt 2) {Write-host "%%s"}}"
)>"%~dp0dummy.txt"
)

How to make a list of arguments which is dropped on a batch file?

I'm trying to create a list of all of the files that are dragged and dropped onto a script, separated by semicolons.
set b =
FOR %%a IN (%*) do (
set "b=%b%%%a;"
) > test.tmp
echo b
pause
This is what I have so far, but the script is not displaying the list of files. What am I doing wrong?
To echo the full paths and filename of the files you are to drag/drop, without double quotes:
#echo off
(for %%a in (%*) do (
echo %%~a;
)
)> test.tmp
type test.tmp
pause
To include double quotes and full path:
#echo off
(for %%a in (%*) do (
echo %%a;
)
)> test.tmp
type test.tmp
pause
to echo filename only, without path:
#echo off
(for %%a in (%*) do (
echo %%~nxa;
)
)> test.tmp
type test.tmp
pause
and to echo filename only, excluding path or extension:
#echo off
(for %%a in (%*) do (
echo %%~na;
)
)> test.tmp
type test.tmp
pause
type test.tmp is just to show you the content of the file after written, you can remove it if you do not need it.
I suggest you also read the help for for command:
for /?
Lastly, if you really want to set a variable (though not needed) you need to enabldelayedexpansion or call echo %%b%% by doubling the %
based on this :
sample code in the file F:\printArguments.bat may be like that:
FOR %%a IN (%*) do (
CALL:PrintTheArgument %%a
)
pause
GOTO:EOF
:PrintTheArgument
echo. %~1
GOTO:EOF
You can test it for example like that:
F:\printArguments.bat "edek" "z" "fabryki" "kredek"
#echo off
setlocal enabledelayedexpansion
set "b="
for %%a in (%*) do (
set "b=!b!%%a;"
)
if defined b (
> test.tmp echo(!b:~0,-1!
)
pause
To append to b in the for loop, delayed expansion may be needed.
Use ! instead of % for delayed expansioned varaibles.
To trim the trailing ;, first check if the variable is defined, then
trim the last character by using -1 in !b:~0,-1!, which gets all
characters from position zero to the 2nd last character.
Note: set b = is variable name of b with a space.
View set /? about how to get substrings from strings.

batch file regex to get specific number from filename

I have a file name
pp-sssss-iiii-12.0.111.22_31-i-P.0.16.1.1
I want from the name only this (output desired):
12.0.111.22_31
then replace . with 0 and remove '_' so I got the below
1200011102231
well I tried to start from something like this
cd %cd%
for %%F in (*.txt) do echo %%~nxF >>1.txt
but I didnt know how to continue
edit , the code :
#ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
SET "sourcedir=C:\Users\moudiz\Desktop\new folder\tttt"
FOR /f "delims=" %%a IN (
'dir /b /a-d "%sourcedir%\*.pbd" '
) DO (
FOR /f "tokens=4delims=-" %%d IN ("%%a") DO (
SET "modname=%%d"
SET "modname=!modname:.=0!"
SET "modname=!modname:_=!"
ECHO %%a becomes !modname!
)
)
GOTO :EOF
pause
the name of the file
P-Script-LogFiles-1.0.33.33_123-IB-P.0.16.357.1.pbd
the output 100033033123
[note: OP belatedly asked for the first token of the name to be prepended to the name generated from the original post, hence use of %%c below]
#ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
SET "sourcedir=U:\sourcedir"
FOR /f "delims=" %%a IN (
'dir /b /a-d "%sourcedir%\*.txt" '
) DO (
echo File "%%a"
FOR /f "tokens=1,4delims=-" %%c IN ("%%a") DO (
SET "modname=%%d"
SET "modname=!modname:.=0!"
SET "modname=!modname:_=!"
ECHO %%a becomes %%c!modname!
)
pause
)
pause
GOTO :EOF
You would need to change the setting of sourcedir to suit your circumstances.
Using delayedexpansion, !var! refers to the modified value of the variable and set "var=!var:string=gnirts!" substitutes "gnirts" for "string" invarand assigns the result back tovar`.
Now - quite what you want to do with this modified result, you don't reveal - but guessing at renaming,
echo ren "%%a" "!modname!"
should be usable
To prepend the first token, simply change the tokens= to 1,4 *to select the first and fourth tokens) - and change the metavariable in the for to %%c (in order that the %%d processing remains the same), then use %%c which will contain the portion of the original filename before the first -.

bat: Listing empty directories, if/else statements within for statements?

I'm trying to write a script that lists every file name in a specified folder, and notifies the user if that folder is empty. So far I've got:
for /r "O:\Mail\5-Friday" %%d in (*.pdf) do (
dir /a /b "%%~fd" 2>nul | findstr "^" >nul && echo %%~nd || echo Empty: Friday
)
but I've no idea where to put the if, else operators.
And is there a way to specify a folder based on user input without rewriting every function for each folder? So instead of:
if /i {%ANS%}=={thursday} (goto :thursday)
if /i {%ANS%}=={friday} (goto :friday)
:thursday
<do stuff>
:friday
<do the same stuff as thursday, but a different directory>
etc, I could write one function with variables in place of paths, assign the directory to a variable, and easily add/remove folders in the code as necessary?
To address the first part of your question, "where to put the if, else operators"... The notation of
command | findstr >nul && echo success || echo fail
... is shorthand for
command | findstr >nul
if ERRORLEVEL 1 (
echo fail
) else (
echo success
)
The magic that happens is in the conditional execution operators, the && and ||. If findstr exits with status zero, then a match was found. Therefore, execute the stuff after &&. Otherwise, status is non-zero, no match was found, so execute the stuff after ||. See how that works?
For the second part, here's a typical way to prompt the user to provide entry based on a finite number of choices.
#echo off
setlocal
:begin
set /p "day=What day? "
for %%I in (monday tuesday wednesday thursday friday) do (
if /i "%day%" equ "%%I" goto %%I
)
goto begin
:monday
call :getdirs "O:\Mail\1-Monday"
goto :EOF
:tuesday
call :getdirs "O:\Mail\2-Tuesday"
goto :EOF
:wednesday
call :getdirs "O:\Mail\3-Wednesday"
goto :EOF
:thursday
call :getdirs "O:\Mail\4-Thursday"
goto :EOF
:friday
call :getdirs "O:\Mail\5-Friday"
goto :EOF
:getdirs <path>
setlocal enabledelayedexpansion
for /f "delims=" %%I in ('dir /b /s /ad "%~1"') do (
dir /b "%%I" 2>NUL | findstr "^" >NUL || echo %%I has no files
)
goto :EOF
Or, even hacksier, I'll do something you probably weren't expecting was possible. I'll have the script open a folder selection dialog to allow the user to select the directory to scan. It's a batch / JScript hybrid script.
If you wish, you can set the root of the folder browser to a ShellSpecialConstants folder by changing the last argument in the next-to-the-last line. Using a value of 0x11 makes the root your system's drives. No value or a value of 0x00 makes the root "Desktop". Or leave the script as-is to set the root as "O:\Mail".
#if (#a==#b) #end /*
:: fchooser2.bat
:: batch portion
#echo off
setlocal
set initialDir="O:\Mail"
for /f "delims=" %%I in ('cscript /nologo /e:jscript "%~f0" "%initialDir%"') do (
call :getdirs "%%I"
)
exit /b
:getdirs <path>
setlocal enabledelayedexpansion
for /f "delims=" %%I in ('dir /b /s /ad "%~1"') do (
dir /b "%%I" 2>NUL | findstr "^" >NUL || (
rem This is where you put code to handle empty directories.
echo %%I has no files
)
)
goto :EOF
:: JScript portion */
var shl = new ActiveXObject("Shell.Application");
var hint = 'Double-click a folder to expand, and\nchoose a folder to scan for empty directories';
var folder = shl.BrowseForFolder(0, hint, 0, WSH.Arguments(0));
WSH.Echo(folder ? folder.self.path : '');
Edit Since apparently BrowseForFolder accepts an absolute directory, there's really no benefit to using PowerShell / C#. The hybrid batch / PowerShell / C# script shall henceforth be retired to the revision history.
This is fun!

batch file: if %variable% (commands)

i want to use my %variable% to manage the conditional clauses in a IF.. THEN.. ELSE in a batch file.
Something like the following:
set variable=%%homedrive%% EQU C:
if %variable% (
echo test ok
) else (
echo test fail
)
if i write on a cmd console:
set test=1 equ 1
if %test% echo OK
it works!
i'll use it in a for /f cicle:
this is my pseudo codethis is my pseudo code to correct
(
rem echo "%systemdrive%;;"
echo "%%COMPUTERNAME%% EQU [x];[some parameters1]"
echo "%%USERNAME%% NEQ [y];[some parameters2]"
echo "%%LOGONSERVER%% EQU [z];[some parameters3]"
[..]
) > "%temp%\CSG_fs.tmp"
[..]
for /f "usebackq tokens=1-2* delims=;" %%a in ("%temp%\CSG_fs.tmp") do (
set cond=%%a& set cond=!cond:~1!
set parm=%%b& set parm=!parm:~0,-1!
echo - cicle: "!cond!" --^> "!parm!"
call if !cond! call:CSG_sub_fs !parm!
echo - done
)
goto:eof
:CSG_sub_fs
[..]
goto:eof
--edit--
how can i use the variable !cond! to decide if execute the call to CSG_sub_fs?
call if !cond! call:CSG_sub_fs !parm!
does not work because it returns: "Can not find the batch label specified - IF"
and if i use
if !cond! call:CSG_sub_fs !parm!
it will say: "call:CSG_sub_fs not expected"
Well - there doesn't seem to be a question, so it's not that easy to answer.
You have a problem with
echo "^%COMPUTERNAME^% EQU [x];[some parameters1]"
because ^ does not escape % - % escapes % - use %%COMPUTERNAME%%...
(you should have been able to check this just by TYPEing "%temp%\CSG_fs.tmp"
Next problem is that
for /f "tokens=1-2* delims=; usebackq" %%a in (%temp%\CSG_fs.tmp) do (
may process the file %temp%\CSG_fs.tmp provided %temp%\CSG_fs.tmp contains no spaces, semicolons or commas. If it contains any of these deafult separators, or certain other characters with a special meaning, then you must enclose the filename in double-quotes "%temp%\CSG_fs.tmp"and use the usebackq option.
You've attempted to use usebackq but DELIMS must be the LAST option if it is used. Your code would set ";","","u","s","e","b","a","c","k" and "q" as delimiters.
Beyond that, perhaps if you explain what you intend to achieve, we'd be able to devise the appropriate code.
Try this:
#ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
CLS
REM I'm setting these variables for testing.
REM That isn't ususally a good idea but the SETLOCAL
REM will ensure they are restored on exit
SET computername=[x]
SET logonserver=[z]
(
rem echo "%systemdrive%;;"
echo "%%COMPUTERNAME%% EQU [x];[some parameters1]"
echo "%%USERNAME%% NEQ [y];[some parameters2]"
echo "%%LOGONSERVER%% EQU [z];[some parameters3]"
) > "%temp%\CSG_fs.tmp"
for /f "usebackqtokens=1-2* delims=;" %%a in ("%temp%\CSG_fs.tmp") do (
set cond=%%a& set "cond=IF !cond:~1! CALL :csg_sub_fs "
set parm=%%b& set parm=!parm:~0,-1!
CALL :varcmd "!cond!" "!parm!"
)
GOTO :eof
:varcmd
%~1 %~2
GOTO :eof
:csg_sub_fs
ECHO parameters supplied to csg_sub_fs were: %*
GOTO :eof
I've forced the variablenames to match the conditions you've used in order to trigger the subroutine calls. Change as you need to prove your concept.
And dont worry about imperfect English. I'm sure I wouldn't do as well in your language!