Use a variable inside a variable in substring in batch file - batch-file

i am trying to get a list of directories , sub directories and files at a given path ,which will be passed at runtime. i dont need the runtime path parameter in the list.
My code is producing file with fully qualified path.
Following is the code that i am trying with :-
#echo off
setlocal EnableDelayedExpansion
set srcf=%~1
for /f "tokens=*" %%a in (' dir /s /b %srcf% ') do ( call :proc "%%a" )
:proc
set var=%~1
set "value=%var: !srcf!=%"
echo !value! >> list.log

instead of:
set "value=%var: !srcf!=%"
try:
set "value=!var: %srcf%=!"
%var: !srcf!=% would delay-expand srcf, keeping the old value of var

Related

Batch file - two questions - exclude file names and move files in a special folder

I have a batch that scans a folder and puts the files in folders depending of the first letter of each file :
setlocal EnableDelayedExpansion
::Fichiers non déplacés
set noms = gamelist.bmp test.gif truc.pdf
FOR /F "tokens=*" %%A in ('DIR /B /A:-D "%cd%\*"') do IF NOT "%%A"=="%~nx0" ( IF NOT "%%A" in %noms% (
set "FIRSTCHAR=%%~nA"
set "FIRSTCHAR=!FIRSTCHAR:~0,1!"
IF NOT EXIST "%cd%\!FIRSTCHAR!" MD "%cd%\!FIRSTCHAR!"
MOVE "%cd%\%%A" "%cd%\!FIRSTCHAR!"
))
I have two noob questions I gave all I have to make this script lol) :
I created an array named "noms" that I want to use to put filenames that won't be affected by the script (they won't be moved in the folder created by the script). Unfortunately, my "IF NOT "%%A" in %noms%" condition doesn't work. What is wrong please ?
Second question : do you think it's possible to put all the files that begin by a number in a unique folder, "0-9" for instance ?
Thanks for the help !
set "noms=gamelist.bmp test.gif truc.pdf"
FOR /F "tokens=*" %%A in ('DIR /B /A:-D "%cd%\*"') do (
set "mouvement=O"
for %%Q in ("%~nx0" %noms%) do if /i "%%~Q"=="%%~nxA" set "mouvement="
if defined mouvement (
Batch is sensitive to spaces in an ordinary string SET statement. SET FLAG = N sets a variable named "FLAGSpace" to a value of "SpaceN"
mouvement is initialised to a value (any value will do) for each filename, but if the filename matches any of the values in noms or the batch filename %~nx0 then it is set to nothing and becomes not defined.

Parse specific strings (2 strings) from multiple text files from a folder

I am trying to parse multiple lines which starts with:
Procedure = xxxxx::xxxx
Description = xxxxxx
Also, I want to ignore SH Library Procedure = $(Stem)_test which has same word Procedure in the .txt file.
I want to search all *.txt files and accumulate date in output file which I will use to upload in req management tool.
Here is the sample of the file:
Harness Lib Greenhills BLD Add Excluded Files = FALSE
Harness Lib Template Project File =
Harness Lib Generated Project File =
Harness Lib Generate Compiler Project File = FALSE
SH Library Procedure = $(Stem)_test
Harness Lib Source Lists Add Excluded Files = FALSE
Harness Lib Substitute Unused Source Files = FALSE
Macro Standard 1 = Set TBRUN_MACRO_STANDARD_1 in Testbed.ini
Procedure = sander_class::sander_class
Member Of = 1
Creation Date = Jun 21 2019 14:36:44
Description = This test is to verify that constructor is called. Req Tested: 67060-SWINTR-73
I have tried below code, but it does not print Procedure and in specific format.
#echo off
(
for /f "tokens=1,*" %%a in ('find "Procedure =" ^< "TEST.txt"') do (
for /f "tokens=1,*" %%d in ('find "Description =" ^< "TEST.txt"') do (
for /f "tokens=1,2 delims=#" %%c in ("%%b") do (
echo(Procedure %%~nxc
echo(
echo(Procedure %%a
echo(
echo(Description %%d
echo(
echo(Path: %%~pb
echo(
)
)
)>"output file.txt"
pause
I need output in below format for all the files (.txt) in same folder:
File Name =
Procedure = sander_class::sander_class
Description = This test is to verify that constructor is called. Req Tested: 67060-SWINTR-73
#ECHO OFF
SETLOCAL
SET "sourcedir=U:\sourcedir"
SET "destdir=U:\destdir"
SET "filename1=%sourcedir%\q57185510.txt"
SET "outfile=%destdir%\outfile.txt"
(
FOR /f "tokens=*" %%a IN (
'findstr /R /b /C:" *Procedure =" /c:" *Description =" "%filename1%" '
) DO ECHO %%a
)>"%outfile%"
GOTO :EOF
You would need to change the settings of sourcedir and destdir to suit your circumstances. The listing uses a setting that suits my system.
I used a file named q57185510.txt containing your data for my testing.
Produces the file defined as %outfile%
I used the one specific file for testing; for all files then set filename1 to a filemask like *.txt.
The findstr looks in all files matching filename1 for lines that /b begin with /r regular-expressions /c:"regex-string" the "regex-string". "regex" here is a small subset of regular expressions, but the particular expressions of interest are for instance Space(any number of)ProcedureSpace= which matches the two lines in question.
The tokens=* suppresses the leading spaces, producing the required lines.
Okay, This should do it but I can't test at the moment.
#(
ECHO OFF
SETLOCAL EnableDelayedExpansion
SET "_FilePath=C:\Admin"
SET "_FileGlob=*.txt"
SET "_MatchRegex1=Procedure =.*::.*$"
SET "_MatchRegex2=Description = .*::.*$"
SET "_ExcludeRegex=^SH Library Procedure =.*$"
SET "_OutputFile=%Temp%\output file.txt"
)
FOR /F "Tokens=*" %%A IN ('
DIR /A-D /S /B "%_FilePath%\%_FileGlob%"
') DO (
SET "_FileName=%%~nxA"
SET "_CurrentFile=!_FileName: =_!"
FOR /F "Tokens=1*" %%a IN ('
FindStr /I /R
/C:"%_MatchRegex1%"
/C:"%_MatchRegex2%"
"%%A"
^| FindStr /I /R /V
/C:"%_ExcludeRegex%"
') DO (
IF NOT DEFINED !_CurrentFile! (
SET "!_CurrentFile!=Found"
ECHO.File Name: !_FileName!
)
ECHO.%%a %%b
)
)>> "_OutputFile"
PAUSE
I will have to come back through and write up exactly what is being done in more detail if needed.
Essentially I am just using a loop of a DIR command to find all of the .txt files in all directories and subdirectories under the given path.
Then I parse that pull out the file name portion and create a variable I can use to match if the file has already been parsed before so that we only print the file name once.
I don't want to print file names at all unless a match was made because I don't think you care to see long lists of files with no matches, but if you prefer that the logic to test if the file name was found previously can be removed and you can just spit out the file name in the first loop
The second loop is looping the results of running a FindStr command on the given file found in the first loop and matching the Regexes which should mean at least two entries per file more if there are more procedures.
FindStr allows sRegex Matches and /V means to exclude any string that matches and pass the rest.

Find the path of executable and store the executable in a variable

I am trying to create a batch file:
The batch file will locate the path of executable first. Then, the path will be stored in a variable for later use.
This is my code:
#echo off
setlocal
set directoryName=dir/s c:\ABCD.exe
rem run command
cmd /c %directoryName%
pause
endlocal
The command prompt does return me with the executable's path but the path is not stored in the variable. Why is it so?
Reading your question, it appears that you're not really wanting to save the path of the executable file at all, but the file name complete with it's full path:
I prefer the Where command for this type of search, this example searches the drive in which the current directory resides:
#Echo Off
Set "mPth="
For /F "Delims=" %%A In ('Where /R \ "ABCD.exe" /F 2^>Nul'
) Do Set "mPth=%%A"
If Not Defined mPth Exit /B
Rem Rest of code goes here
The variable %mPth% should contain what you need. I have designed it to automatically enclose the variable value in doublequotes, if you wish to not have those, change %%A on line 4 to %%~A. If the file is not found then the script will just Exit, if you wish it to do something else then you can add that functionality on line 5.
Note: the code could find more than one match, if it does it will save the variable value to the last one matched, which may not be the one you intended. A robust solution might want to include for this possibility.
Edit (this sets the variable, %mPth% to the path of the executable file only)
#Echo Off
Set "mPth="
For /F "Delims=" %%A In ('Where /R \ "ABCD.exe" /F 2^>Nul'
) Do Set "mPth=%%~dpA"
If Not Defined mPth Exit /B
Set "mPth=%mPth:~,-1%"
Rem Rest of code goes here
Lets walk through your code
set directoryName=dir/s c:\ABCD.exe
This fills the variable directory name with the value dir/s c:\ABCD.exe.
cmd /c %directoryName%
This executes the command in directoryname. There is no line in your code that saves the files location to a variable.
Extracting the path of a file can be done as follows
#echo off
setlocal
set executable=c:\location\ABCD.exe
FOR %%A IN ("%executable%") DO Set executablepath=%%~dpA
echo executablepath: %executablepath%
pause
endlocal
%executablepath% will contain c:\location\
The value that you are assigning to directoryname is dir /s c:\abc.exe.
this value is then substituted for %directoryname% in your cmd line, which executes the command dir/s..., showing you the location(s) of abc.exe in the familiar dir format.
If what you want is just the directoryname in directoryname, then you need
for /f "delims=" %%a in ('dir /s /B /a-d "c:\abc.exe"') do set "directoryname=%%~dpa"
which will first execute the dir command, then process each line of output from that command and assign it in its entirety to %%a.
The dir command shown would "display" the matching names found in the nominated directory (c:\) and its subdirectories (/s) in basic form (/b) - that is, names only, no size or date or report-headers or report-footers, and a-d without directorynames (should they match the "mask" abc.exe)
The delims= option to the for /f command instructs that the entire line as output by the command in single-quotes, be assigned to %%a.
When the result is assigned to the variable directoryname, only the Drive and Path parts are selected by using the ~dp prefix the the a.
Note that only the very last name found will be assigned to the variable as any earlier assignment will be overwritten by a succeeding assignment.
This may or may not be what you are looking for. This script searches through the PATH variable and looks for files that have and extension in the PATHEXT variable list.
#SETLOCAL ENABLEEXTENSIONS ENABLEDELAYEDEXPANSION
#SET EXITCODE=1
:: Needs an argument.
#IF "x%1"=="x" (
#ECHO Usage: %0 ^<progName^>
GOTO TheEnd
)
#set newline=^
#REM Previous two (2) blank lines are required. Do not change!
#REM Ensure that the current working directory is first
#REM because that is where DOS looks first.
#PATH=.;!PATH!
#FOR /F "tokens=*" %%i in ("%PATH:;=!newline!%") DO #(
#IF EXIST %%i\%1 (
#ECHO %%i\%1
#SET EXITCODE=0
)
#FOR /F "tokens=*" %%x in ("%PATHEXT:;=!newline!%") DO #(
#IF EXIST %%i\%1%%x (
#ECHO %%i\%1%%x
#SET EXITCODE=0
)
)
)
:TheEnd
#EXIT /B %EXITCODE%
Note that this may find multiple executables. It may also find multiple types of executables. The current directory is also included first since that is what the shell, cmd.exe, does.
M:>whence wc
.\wc.BAT
.\wc.VBS
C:\Users\lit\bin\wc.BAT
C:\Users\lit\bin\wc.VBS

Batch Script assistance needed

Happy Friday Think-Tank!
I need some assistance with a Batch .BAT script. Specifically I need help with some "IF statement syntax"
I have a script that is renaming files. There are two files, one ending in four digits and the other ending in five digits. The files will be renamed with variables I have already pre-set earlier within my script.
So here is a scenario: We have two files in a directory located at
c:\Users\username\Desktop\test-dir
There are two files within test-dir:
file1.12345
file2.1234
A four digit ending is one variable type (VAR1), whereas a file ending in five digits is another variable type (VAR2).
I need an if statement to:
a) read all the files(s) with the chosen directory (without using a wildcard if possible).
b) determine based on the number of digits after the "." which variable to use.
c) once making that determination rename the file with the appropriate variables.
The final re-naming convention is as so: yyyymmddtype.1234/12345
So basically it would use the datestamp variable I already created, the type variable I already created to be injected by the if statement, and append with the original ending digits of the file.
I know this seems like a lot, but I am more so a bash script guy. I have all the elements in place, I just need the if statement and what feels like a for loop of some kind to tie it all together.
Any help would be great!
Thank you!
Sorry, not the option you where asking for. Instead of iterating over the full list checking each file for extension conformance, iterate over a list of patterns that will filter file list, renaming matching files with the asociated "type"
for %%v will iterate over variable list, for %%a will split the content of the variable in pattern and type, for %%f will generate the file list, filter with findstr using the retrieved pattern and rename matching files with the corresponding "type"
Rename command is preceded with a echo to output commands to console. If the output is correct, remove the echo to rename the files.
#echo off
rem Variables defined elsewhere
set "folder=c:\somewhere"
set "timestamp=yyyymmdd"
rem Rename pattern variables in the form pattern;type
set "var1=\.....$;type1"
set "var2=\......$;type2"
set "var1=\.[^.][^.][^.][^.]$;type1"
set "var2=\.[^.][^.][^.][^.][^.]$;type2"
setlocal enableextensions disabledelayedexpansion
for %%v in ("%var1%" "%var2%") do for /f "tokens=1,* delims=;" %%a in ("%%~v") do (
for /f "tokens=*" %%f in ('dir /a-d /b "%folder%" ^| findstr /r /c:"%%~a"') do (
echo ren "%folder%\%%~f" "%timestamp%%%~b%%~xf"
)
)
endlocal
#ECHO OFF &SETLOCAL
set "yyyymmdd=yyyymmdd"
set "VAR1=VAR1"
set "VAR2=VAR2"
for /f "delims=" %%a in ('dir /b /a-d^|findstr /re ".*\....."') do echo(ren "%%~a" "%yyyymmdd%%VAR1%%%~xa"
for /f "delims=" %%a in ('dir /b /a-d^|findstr /re ".*\......"') do echo(ren "%%~a" "%yyyymmdd%%VAR2%%%~xa"
remove echo( to get it working.
If I understand you then this will rename the two files using preset variables for each one:
for %%a in ("%userprofile%\Desktop\test-dir\*") do (
if "%%~xa"==".12345" ren "%%a" "%variableA%-%variableB%%%~xa"
) else (
ren "%%a" "%variableC%-%variableD%%%~xa"
)
)

batch: filenames with variables evaluated inside a for loop

File names and directories containing variables are being evaluated indside procedures. How do I make batch store the file's name as a variable without evaluating it?
EG: my path is:
"C:\Rare\Names in a File\%CD%\"
batchfile.bat
file.txt
I want to run a script inside this directory:
REM #####BATCHFILE.BAT#######
pushd "%dp0"
for %%A in ("C:\Test") do set EXEPATH=%%~A
for %%A in ("Test.exe") do set EXECUTABLE=%%~A
for %%A in ("%CD%") do set DIRNAME=%%~A
for %%A in ('dir /b /a-d "*.txt"') do (
SET FILENAME=%%~A
CALL :PROCEDURE
)
exit /b
:PROCEDURE
start /w "" "%EXEPATH%\%EXECUTABLE%" "%DIRNAME%\%FILENAME%"
I have made a menu in batch which is a little bit different to your problem.
You need to have one variable per file. The easiest way is to just increment their names:
var1=path1\exe1
var2=path1\exe2
var3=path2\exe1
var4=path2\exe2
On each variable in the for loop you could call a procedure which saves the file with the path in a variable.
for ....(
call :Var %path% %file%
)
:Var
set /a id+=1
set %id%.path=%1&& shift
set %id%.file=%1
goto:EOF
after this you could do
for ..(1,1,%id%) do (
start !%id%.path!\!%id%.file!
)
if you want to have a look at my Batch menu, you can contact me.

Resources