find multiple files paths with single string - shell

I tried to write a batch script that find all the paths of files that have the same name as the input string. right now it can find only the first file found, and i cant think of a way to make it list multiple files locations. I am not very experienced and I need some help.
this is part of the script code:
:start
cls
echo Enter file name with extension:
set /p filename=
echo Searching...
for %%a in (C D E F G H U W) do (
for /f "tokens=*" %%b in ('dir /s /b "%%a:\%filename%"') do (
set file=%%~nxb
set datapath=%%~dpb\
::the path of the file without the filename included "C:\folder\folder\"
set fullpath=%%b
::the path of the file with the filename included "C:\folder\folder\file"
goto break
)
)
:notfound
cls
echo Enter file name with extension:
echo %filename%
echo File Not Found!
ping localhost -n 4 >nul
goto start
:break
if "%datapath:~-1%"=="\" set datapath=%datapath:~,-1%
cls
echo 3 %filename% found
echo %fullpath1%
echo %fullpath2%
echo %fullpath3%
--- || ---
I want the script to search the computer and list every encountered files with the same name and I want to be able to put those files' paths into different variables.
For example, if readme.txt is the input, then I want the list of all the paths of all the files with that specific name (readme.txt) and I want to set variable for each path so I can use it after that.
input:
readme.txt
output:
3 files found
C:\folder\folder\readme.txt
C:\folder\folder\folder\readme.txt
D:\folder\readme.txt

#echo off
set filename=readme.txt
for %%a in (C D E F G H U W) do (
for /f "tokens=*" %%b in ('dir /s /b "%%a:\%filename%"') do (
echo you can do something here with %%~nxb in %%~dpb
echo full name: %%b
)
)
I see no need to set the filenames to variables, as you can process them inside your loop. But if you really need them (for some reason) in variables:
#echo off
setlocal enabledelayedexpansion
set filename=readme.txt
set count=0
for %%a in (C D E F G H U W) do (
for /f "tokens=*" %%b in ('dir /s /b "%%a:\%filename%" 2^>nul') do (
set /a count+=1
set _file[!count!]=%%b
)
)
set _file

You can try with this code :
#echo off
Title Searching for the path with the same file name
Mode con cols=80 lines=3 & Color 9E
SET /a Count=0
set /a cnt=1
set "FileName=Readme.txt"
set "Report=%~dp0Report.txt"
set "Folder2Copy=%~dp0Readme_Folder"
set "Result2Copy=%~dp0Result2Copy.txt
If exist %Folder2Copy% RD /S /Q %Folder2Copy%
If Exist %Report% Del %Report%
If Exist %Result2Copy% Del %Result2Copy%
echo(
Echo Searching for the path with the same file name
Rem Looking for fixed drives and store them into variables
SETLOCAL enabledelayedexpansion
For /f "skip=1" %%a IN ('wmic LOGICALDISK where driveType^=3 get deviceID') DO (
for /f "delims=" %%b in ("%%a") do (
SET /a "Count+=1"
set "Drive[!Count!]=%%b"
)
)
:Display
for /L %%i in (1,1,%Count%) do (
cls
Title Please wait a while ... Searching for "%FileName%" on "!Drive[%%i]!\"
echo(
echo Please wait a while ... Searching for "%FileName%" on "!Drive[%%i]!\"
Call :FindPathFile !Drive[%%i]!\ %FileName% >> %Report%
)
Start "" %Report%
Goto :AskQuestion
::***************************************************************************************
:FindPathFile <Location> <FileName>
Where.exe /r %1 %2
Goto :eof
::***************************************************************************************
:AskQuestion
cls & Mode con cols=100 lines=5
echo(
echo Did you want to make copy of all files found as name "%FileName%"
echo saved on "%Report%" ? (Y/N) ?
set /p "Input="
If /I "%INPUT%"=="Y" (
for /f "delims=" %%i in ('Type "%Report%"') do (
Call :MakeCopy "%%~i" "%Folder2Copy%\"
)
)
Call :Explorer "%Folder2Copy%\" & exit
If /I "%INPUT%"=="N" (
Exit
)
Goto :eof
::***************************************************************************************
:MakeCopy <Source> <Target>
If Not Exist "%~2\" MD "%~2\" (
if not exist "%2\%~n1" (
echo copying "%~1" to "%~2"
copy /N /B "%~1" "%~2" >>%Result2Copy% 2>&1
) else (
call :loop "%~1" "%~2"
)
)
::***************************************************************************************
:loop
set "fname=%2\%~n1(%cnt%)%~x1"
if exist "%fname%" set /a cnt+=1 && goto :loop
copy "%~1" "%fname%"
exit /b
::***************************************************************************************
:Explorer <file>
explorer.exe /e,/select,"%~1"
Goto :EOF
::***************************************************************************************

Related

Looping through %1 as a directory in batch?

I've searched the web for answers but can't seem to find an answer. I want the user to provide a directory and to be able to loop through it. I'm able to loop through the current directory like so:
#Echo off
for /r %%f in (*.*) do (
echo %%f
)
But then when I try to do the same by looping through %1, I can't get the result I'm looking for. What am I doing wrong? Here's where I'm at in the batch file:
#Echo off
if exist %1 (
for /r %%f in (%1) do (
echo %%f
)
) else (
echo "That directory does not exist."
)
I've tried using /D but all that did was echo the directory I provided like this:
FileCount C:\Users\Me\Desktop
> C:\Users\Me\Desktop
Edit: My goal for this program is to eventually count the number of files within the given directory. I expect the directory to be provided as it's absolute path and I'll be executing this file through cmd. Here's an example of the input I'm expecting.
FileCount C:\Users\Me\Desktop
And the desired output would be something like:
> Hello world.txt
> Cat.png
> There are 2 files within this directory.
Side-note: I don't want to filter out the output of the dir command, I want to do this with a for loop.
Here's what you asked for, plus the optional recurs feature. Note that this will miss hidden files and directories.
#setlocal EnableExtensions
#prompt=$G
#set _Error_Success=0
#set _Error_PathNotFound=3
#if "%~1" equ "/?" goto :Usage
#if "%~1" equ "" goto :Usage
#if "%~1" equ "/r" (#set _recurs=/r & #set _root=%~2) else (#set _root=%~1)
#if not exist "%_root%" goto :Oops
#set count=0
#pushd "%_root%"
#for %_recurs% %%f in (*) do #call :Counter "%%f"
#popd
#echo There are %count% entries within this directory.
#exit /b %_Error_Success%
:Counter
#set /a count+=1
#echo %~1
#exit /b %_Error_Success%
:Oops
#echo "That directory does not exist."
#exit /b %_Error_PathNotFound%
:Usage
#echo Usage: FileCount [/r] path
And this uses the dir command, without resorting to invoking findstr:
#setlocal EnableExtensions
#prompt=$G
#set _Error_Success=0
#set _Error_PathNotFound=3
#set _Error_InvalidParameter=87
#set _attributes=
#set _recurs=
#set _count=0
#if "%~1" equ "/?" #goto :Usage & #exit
#if "%~1" equ "" goto :Usage
#set _root=%~1
#if not exist "%_root%" goto :Oops
#shift
#pushd "%_root%"
for /f %%G in ('dir /B /A-d %1 %2 %_root%') do #call :Counter "%%G"
#popd
#echo There are %_count% entries within this directory.
#exit /b %_Error_Success%
:Counter
#set /a _count+=1
#echo %~1
#exit /b %_Error_Success%
:HandleOptions
:Oops
#echo "That directory does not exist."
#exit /b %_Error_PathNotFound%
:Usage
#echo Usage: FileCount [/A<Attributes>] [/S] rootPath
#echo Where <Attributes> corresponds to 'dir /A' optiions (see 'help dir')
#echo and /S will cause recursion into subdirectories of rootPath.
This example, uses a for loop, and does not use the dir command, as per your inexplicable request, but it does use xcopy to list and count the files within it instead:
#For %%G In ("%~1") Do #If "%%~aG" Lss "d" (If "%%~aG" GEq "-" (
Echo Error: File argument given, expected a directory.
%SystemRoot%\System32\timeout.exe /T 3 /NoBreak 1> NUL
Exit /B 1) Else (
Echo Error: Invalid argument, directory path expected.
%SystemRoot%\System32\timeout.exe /T 3 /NoBreak 1> NUL
Exit /B 1)
) Else Echo File content of "%~1":& For /F Delims^= %%H In (
'%SystemRoot%\System32\xcopy.exe "%~1" : /HIL') Do #Echo %%~nxH
#%SystemRoot%\System32\timeout.exe /T -1 & Exit /B 0
If you want it to recurse the input directory, then I'd suggest this very small modification:
#For %%G In ("%~1") Do #If "%%~aG" Lss "d" (If "%%~aG" GEq "-" (
Echo Error: File argument given, expected a directory.
%SystemRoot%\System32\timeout.exe /T 3 /NoBreak 1> NUL
Exit /B 1) Else (
Echo Error: Invalid argument, directory path expected.
%SystemRoot%\System32\timeout.exe /T 3 /NoBreak 1> NUL
Exit /B 1)
) Else Echo File content of "%~1":& For /F Delims^= %%H In (
'%SystemRoot%\System32\xcopy.exe "%~1" : /HILS') Do #Echo %%H
#%SystemRoot%\System32\timeout.exe /T -1 & Exit /B 0
Or with a little more work, outputting relative paths instead:
#For %%G In ("%~1") Do #If "%%~aG" Lss "d" (If "%%~aG" GEq "-" (
Echo Error: File argument given, expected a directory.
%SystemRoot%\System32\timeout.exe /T 3 /NoBreak 1> NUL
Exit /B 1) Else (
Echo Error: Invalid argument, directory path expected.
%SystemRoot%\System32\timeout.exe /T 3 /NoBreak 1> NUL
Exit /B 1)
) Else Echo File content of "%~1":& For /F Delims^= %%H In (
'%SystemRoot%\System32\xcopy.exe "%~1" : /HILS') Do #(
Set "}=%%H" & SetLocal EnableDelayedExpansion
For %%I In ("!}:*%~1=.!") Do #EndLocal & Echo %%~I)
#%SystemRoot%\System32\timeout.exe /T -1 & Exit /B 0
setlocal enabledelayedexpansion
rem Put it into a folder that is in ENV PATH variable.
rem So, you can call it from wherever you want.
if not "%~1"=="" (
if exist "%~dpn1" (
set /a "filecount=0"
for /f "tokens=* delims=" %%f in ('dir /b "%~dpn1"') do (
echo %%f
set /a "filecount+=1"
)
echo:
echo In "%~dpn1" found !filecount! file^(s^).
) else (
echo:
echo [ERROR] Invalid input. Please specify:
echo 1. A full path.
echo 2. A folder in cwd.
echo:
echo If input is empty, current working directory (cwd)
echo will be considered.
exit /b 1
)
) else (
set /a "filecount=0"
for /f "tokens=* delims=" %%f in ('dir /b "%~dp0"') do (
echo %%f
set /a "filecount+=1"
)
echo:
echo In "%~dp0" found !filecount! file^(s^).
)
endlocal
If you want it recursive call it as progname.bat /r [foldname]:
setlocal enabledelayedexpansion
rem Put it into a folder that is in ENV PATH variable.
rem So, you can call it from wherever you want.
if "%1"=="/r" shift
if not "%1"=="" (
if exist "%~dpn1" (
set /a "filecount=0"
set /a "totalcount=0"
set "oldroot=%~dpn1"
for /f "tokens=* delims=" %%f in ('dir /b /s "!cd!"') do (
if not "%%~dpf"=="!oldroot!" (
echo:
echo In "!oldroot!" found !filecount! file^(s^).
echo:
set /a "filecount=0"
set "oldroot=%%~dpf"
)
echo --- %%f
set /a "filecount+=1"
set /a "totalcount+=1"
)
echo:
echo In "%~dpn1" found !totalcount! file^(s^).
) else (
echo:
echo [ERROR] Invalid input. Please specify:
echo 1. A full path.
echo 2. A folder in cwd.
echo:
echo If input is empty, current working directory (cwd)
echo will be considered.
exit /b 1
)
) else (
set /a "filecount=0"
set /a "totalcount=0"
set "oldroot=!cd!"
for /f "tokens=* delims=" %%f in ('dir /b /s "!cd!"') do (
if not "%%~dpf"=="!oldroot!" (
echo:
echo In "!oldroot!" found !filecount! file^(s^).
echo:
set /a "filecount=0"
set "oldroot=%%~dpf"
)
echo --- %%f
set /a "filecount+=1"
set /a "totalcount+=1"
)
echo:
echo In "%~dp0" found !totalcount! file^(s^).
)
endlocal
Try it and see if it is what you expected.
Thank you for the help everybody, I've found the solution to the problem and it was very simple. All I needed to do was loop through %1\*.* instead of %1 itself.
#Echo off
if exist %1 (
for %%f in (%1\*.*) do (
echo %%f
)
) else (
echo "That directory does not exist."
)

Use a Batch File to list files and allow the user to select which file to copy into a new destination

I am a newbie to Windows Scripting.
I am trying to list some txt files in several sub directories & want to copy a user selected file to a new destination. Please note that the file name is unique in different locations.
I got the first part to work (Listing out the files & locations) using the following script, but I am unable to copy the selected file to the new location.
#ECHO OFF
SET index=1
SETLOCAL ENABLEDELAYEDEXPANSION
SET FFPath="C:\Scripts - Backup Server\DKXpress_bkp"
SET NewPath=C:\DKServer
ECHO Recursively searching %FFPath%
echo.
FOR /F "delims=" %%f in ('DIR %FFPath%\*.txt /a:-d /s /b') DO (
SET file!index!=%%f
ECHO !index! - %%f
SET /A index=!index!+1
)
SETLOCAL DISABLEDELAYEDEXPANSION
SET /P selection="select file by number:"
SET file%selection% >nul 2>&1
IF ERRORLEVEL 1 (
ECHO invalid number selected
EXIT /B 1
)
SET NewFile=file%selection%
ECHO Copying %NewFile% to %NewPath%
ECHO.
COPY /Y "%NewFile%" "%NewPath%"
ECHO.
PAUSE
I think I am doing this part wrong
SET NewFile=file%selection%
Thank you all in advance
You don't need to set an index variable or delayed expansion, if you let Find do the work for you:
#Echo Off
Set "FFPath=C:\Scripts - Backup Server\DKXpress_bkp"
Set "NewPath=C:\DKServer"
Echo Recursively searching %FFPath%
Echo=
For /F "Delims==" %%A In ('"Set File[ 2>Nul"') Do Set "%%A="
For /F "Tokens=1* Delims=]" %%A In (
'"Dir /B/S/A-D-S-L "%FFPath%\*.txt" 2>Nul|Find /N /V """') Do (
Echo %%A] %%B
Set "File%%A]=%%B"
)
Echo=
Set /P "#=Select file by number: "
Echo=
For /F "Tokens=1* Delims==" %%A In ('"Set File[%#%] 2>Nul"') Do (
Echo Copying %%B to %NewPath%&Echo=
Copy /Y "%%B" "%NewPath%"
GoTo :End
)
Echo Invalid number selected
:End
Echo=
Pause
You need to use delayed expansion to get the file name assigned to the variable correctly.
SET NewFile=!file%selection%!
Remove the setlocal to disable delayed expansion.
You can try something like that :
#ECHO OFF
:Main
cls
SET index=1
SETLOCAL ENABLEDELAYEDEXPANSION
SET FFPath="C:\Scripts - Backup Server\DKXpress_bkp"
SET "NewPath=C:\DKServer"
ECHO Recursively searching %FFPath%
echo.
FOR /F "delims=" %%f in ('DIR %FFPath%\*.txt /a:-d /s /b') DO (
SET filepath[!index!]=%%f
ECHO [!index!] - %%~nxf - %%f
SET /A index=!index!+1
)
echo(
echo select file by number :
set /p Input=""
For /L %%i in (1,1,%index%) Do (
If "%INPUT%" EQU "%%i" (
ECHO Copying "!filepath[%%i]!" to "!NewPath!"
COPY /Y "!filepath[%%i]!" "!NewPath!"
)
)
echo Copying another file ? (Y = Yes or N = No) ?
set /p input2=""
If /I "!input2!"=="Y" (
goto :Main
) else (
goto :eof
)

Find string in multiple .txt files

I have a folder with many .txt files. I would like to find string "X" in all of these files then I would like to copy the found strings into .txt files into a different folder.
So far I have tried :
#echo on
findstr /m "X" "%userprofile%\Desktop\New_Folder\New_Folder\*.txt"
if %errorlevel%==0 do (
for %%c in (*.txt) do (
type %%c >> "%UserProfile%\Desktop\New_Folder\%%~nc.txt"
pause
I do not understand the output %%~nc.txt part it's suppost to copy the changed .txt files to a new folder with the same name.
I would like to point out that string "X" is found in different places in the .txt file.
This batch file can did the trick (-_°)
So, just give a try : ScanfilesWordSearch_X.bat
#ECHO OFF
::******************************************************************************************
Title Scan a folder and store all files names in an array variables
SET "ROOT=%userprofile%\Desktop"
Set "NewFolder2Copy=%userprofile%\Desktop\NewCopyTxtFiles"
SET "EXT=txt"
SET "Count=0"
Set "LogFile=%~dp0%~n0.txt"
set "Word2Search=X"
SETLOCAL enabledelayedexpansion
REM Iterates throw the files on this current folder and its subfolders.
REM And Populate the array with existent files in this folder and its subfolders
For %%a in (%EXT%) Do (
Call :Scanning "%Word2Search%" "*.%%a"
FOR /f "delims=" %%f IN ('dir /b /s "%ROOT%\*.%%a"') DO (
( find /I "%Word2Search%" "%%f" >nul 2>&1 ) && (
SET /a "Count+=1"
set "list[!Count!]=%%~nxf"
set "listpath[!Count!]=%%~dpFf"
)
) || (
( Call :Scanning "%Word2Search%" "%%~nxf")
)
)
::***************************************************************
:Display_Results
cls & color 0B
echo wscript.echo Len("%ROOT%"^) + 20 >"%tmp%\length.vbs"
for /f %%a in ('Cscript /nologo "%tmp%\length.vbs"') do ( set "cols=%%a")
If %cols% LSS 50 set /a cols=%cols% + 20
set /a lines=%Count% + 10
Mode con cols=%cols% lines=%lines%
ECHO **********************************************************
ECHO Folder:"%ROOT%"
ECHO **********************************************************
If Exist "%LogFile%" Del "%LogFile%"
rem Display array elements and save results into the LogFile
for /L %%i in (1,1,%Count%) do (
echo [%%i] : !list[%%i]!
echo [%%i] : !list[%%i]! -- "!listpath[%%i]!" >> "%LogFile%"
)
(
ECHO.
ECHO Total of [%EXT%] files(s^) : %Count% file(s^) that contains the string "%Word2Search%"
)>> "%LogFile%"
ECHO(
ECHO Total of [%EXT%] files(s) : %Count% file(s)
echo(
echo Type the number of file that you want to explore
echo(
echo To save those files just hit 'S'
set /p "Input="
For /L %%i in (1,1,%Count%) Do (
If "%INPUT%" EQU "%%i" (
Call :Explorer "!listpath[%%i]!"
)
IF /I "%INPUT%"=="S" (
Call :CopyFiles
)
)
Goto:Display_Results
::**************************************************************
:Scanning <Word> <file>
mode con cols=75 lines=3
Cls & Color 0E
echo(
echo Scanning for the string "%~1" on "%~2" ...
goto :eof
::*************************************************************
:Explorer <file>
explorer.exe /e,/select,"%~1"
Goto :EOF
::*************************************************************
:MakeCopy <Source> <Target>
If Not Exist "%~2\" MD "%~2\"
Copy /Y "%~1" "%~2\"
goto :eof
::*************************************************************
:CopyFiles
cls
mode con cols=80 lines=20
for /L %%i in (1,1,%Count%) do (
echo Copying "!list[%%i]!" "%NewFolder2Copy%\"
Call :MakeCopy "!listpath[%%i]!" "%NewFolder2Copy%">nul 2>&1
)
Call :Explorer "%NewFolder2Copy%\"
Goto:Display_Results
::*************************************************************
#ECHO OFF
SETLOCAL
SET "sourcedir=U:\sourcedir"
SET "destdir=U:\destdir"
SET "mystring=x"
FOR %%a IN ("%sourcedir%\*.txt") DO FINDSTR "%mystring%" "%%a">nul&IF NOT ERRORLEVEL 1 FINDSTR "%mystring%" "%%a">"%destdir%\%%~nxa"
GOTO :EOF
You would need to change the settings of sourcedir and destdir to suit your circumstances and set mystring appropriately, noting that you may have to adjust the findstr switches to accomodate case, literal and space-in-target-string.
Naturally, you could code sourcedir etc. directly as literals, but doing it this way means that the relevant strings need only be changed in one place.
You are close, but checking the ErrorLevel of findstr does not make sense here as this reflects the overall result, that is, ErrorLevel is set to 0 in case any of the files contain the search string.
I would parse the output of findstr /M using a for /F loop and copy the returned files in the body:
for /F "eol=| delims=" %%F in ('
findstr /M /I /C:"X" "%USERPROFILE%\Desktop\New_Folder\New_Folder\*.txt"
') do (
copy "%%F" "%USERPROFILE%\Desktop\New_Folder\"
)
This copies all those files which contain the literal search string (in a case-insensitive manner).

How to create a unique output filename for Windows Script?

I am trying to create a windows script that should generate this kind of filename everytime I run it: filename1, filename2, filename3 and so on. Here is what I have so far:
(
#echo off
wmic logicaldisk get size,freespace,caption
) > disk.txt
I hope you can help me. Thanks!!
:: make a tempfile
:maketemp
SET "tempfile=%temp%\%random%"
IF EXIST "%tempfile%*" (GOTO maketemp) ELSE (ECHO.>"%tempfile%a")
You now have any number of filenames available.
%tempfile%a exists and is empty, but %tempfile%anythingelse should be available for use.
#ECHO OFF
SETLOCAL
SET "basename=filename"
SET /a outname=0
:genloop
SET /a outname+=1
IF EXIST "%basename% %outname%.txt" GOTO genloop
SET "outname=%basename% %outname%.txt"
ECHO %outname%
GOTO :EOF
Ah - increment the destination filename on each run. This should do that. It's not actually creating a file - you'd need to create the file %outname% each time to have it increment...
(the space between %basename% and %outname% is optional, of course - omit it if desired.)
edited to include .txt
This will give you up to 1000 filenames but you can go higher, up to 2 Billion, but the higher you go the longer the delay will be before it picks a filename.
#echo off
for /L %%a in (1,1,1000) do if not defined filename if not exist "filename%%a.txt" set "filename=filename%%a.txt"
(
wmic logicaldisk get size,freespace,caption
) > "%filename%"
#echo off
setlocal enableextensions
call :getNextFilename "filename*.txt" nextFilename
echo %nextFilename%
echo test > "%nextFilename%"
call :getNextFilename "%cd%\filename*.txt" nextFilename
echo %nextFilename%
echo test > "%nextFilename%"
endlocal
exit /b
:getNextFilename whatToSearch returnVariable
setlocal enableextensions enabledelayedexpansion
for /f %%a in ("$\%~1"
) do for /f "tokens=1,* delims=*" %%b in ("%%~nxa"
) do ( set "left=%%b" & set "right=%%c" )
set "max=0"
for %%a in ("%~1"
) do for /f "tokens=1 delims=%left%%right% " %%b in ("%%~nxa"
) do for /f "tokens=* delims=0 " %%c in ("0%%~b"
) do if %%~c geq !max! set /a "max=%%c+1"
endlocal & set "%~2=%~dp1%left%%max%%right%" & exit /b
This should find the next file in sequence independently of the existence of holes in the numeration of the files. A path can be included or omitted. The * will be used as the placeholder for the numeration. BUT this will not work if files or included paths have "problematic" characters.
If the date/time of creation of the file can be considered, then this version can be optimized as
:getNextFilename whatToSearch returnVariable
setlocal enableextensions disabledelayedexpansion
for /f %%a in ("$\%~1"
) do for /f "tokens=1,* delims=*?" %%b in ("%%~nxa"
) do ( set "left=%%b" & set "right=%%c" )
set "max=0"
for /f "delims=" %%a in ('dir /tc /o-d /b "%~1" 2^>nul'
) do for /f "tokens=1 delims=%left%%right% " %%b in ("%%~nxa"
) do for /f "tokens=* delims=0 " %%c in ("0%%~b"
) do set /a "max=%%c+1" & goto done
:done
endlocal & set "%~2=%~dp1%left%%max%%right%" & exit /b
that will take the latest created instance of the file set.
I finally figured out where to put the .txt extension. This is from #Magoo's answer but I wanted the file to be a text file so I placed the .txt twice in order for it to work properly.
#ECHO OFF
SETLOCAL
SET "basename=DISK-OUT"
SET /a outname=0
:genloop
SET /a outname+=1
IF EXIST "%basename% %outname%.txt" GOTO genloop
SET "outname=%basename% %outname%.txt"
(
wmic logicaldisk get size,freespace,caption
) > "%outname%"
GOTO :EOF

for command is executed only for the first value when a label is inside

I have the script
for /f "delims=" %%i in ('dir "%folder%*.txt" /b /s') do (
set s=%%i
set s=!s:%folder%=!
set new_s=!s:\=!
if "x!new_s!" NEQ "x!s!" (
:ProcessListSource
For /f "tokens=1* delims=\" %%A in ("!s!") do (
if "%%A" NEQ "" (
if "!Folder1!" NEQ "" (
Set Folder1=!Folder1!\!Name!
)else (
Set Folder1=!Name!
)
Set Name=%%A
)
if "%%B" NEQ "" (
set s=%%B
goto :ProcessListSource
)
)
echo Folder is: !Folder1!
echo Name is: !Name!
echo ---------------------
) else (
echo Not a folder !s!
)
)
but it does not work as I would have expected:
The first for is executed only once and also the last echo is printed on the screen.
Given a folder I need the files from subfolders without the given folder and than split them into the folder and file
Ex: folder=C:\test
The for would give me the file C:\test\test1\test2\t.txt
And I need test1\test2 and t.txt
GOTO breaks your FOR /F \ IF context and they can be executed only once.
More simple example:
#echo off
for /l %%S in (1=1=5) do (
echo %%S
goto :inner_label
rem
:inner_label
rem
)
This will print only 1 . Do you really need the GOTO here?
When the parser reads your code, all the code inside your for loop is "considered" as only one command that is readed, parsed and executed. As stated in the npocmaka answer, any goto call takes you out of this "line" of code, ending the process of the for loop.
This is a alternative. Use pushd + xcopy /l /s commands to generate a list of the relative paths of the files.
#echo off
setlocal enableextensions disabledelayedexpansion
set "folder=%cd%"
pushd "%folder%"
for /f "delims=" %%a in ('xcopy /l /s /y * "%temp%"^|findstr /vbr /c:"[0-9]"'
) do for /f "delims=: tokens=1,*" %%b in ("%%~a") do (
echo [%%c] [%%~nxa]
)
popd

Resources