How search in multiple directories - windows

start.bat
#echo off
CALL bat.bat "C:\Users\admin\Documents\test 2,C:\Users\admin\Documents\test 1" "*.xml *.txt *.html" "D:\Work\bat\batLog.txt"
bat.bat
for %%G in (%1) do (
echo %%~G
pushd "%%G"
If Exist "%%G" (
for /R %%H in ("%2") do (
if %%~zH LSS %3 (
>>"%4" (
echo %%~H
echo %%~tH
for /f "tokens=* delims=," %%i in ('type "%%~H"') do (
echo %%i
))) popd)))
pause
exit/b
why does not it go to the next directory? Echo only test 2

This is now a complete rewrite using your new code. This should get you closer to what you want to do. Hopefully I fixed all the other errors with your program. I purposely indent my code so that I can see where a code block begins and ends. Much easier to see and understand how the code is working.
start.bat
#echo off
call bat.bat "C:\Users\admin\Documents\test 2,C:\Users\admin\Documents\test 1" "*.xml *.txt *.html" "20000" "D:\Work\bat\batLog.txt"
bat.bat
#echo off
REM %1 = List of Folders
REM %2 = List of file masks
REM %3 = File Size for comparison
REM %4 = Log File
set "folders=%1"
set "folders=%folders:,=","%"
for %%G in (%folders%) do (
echo %%~G
If Exist "%%~G" (
pushd "%%~G"
for /R %%H in (%~2) do (
if %%~zH LSS %~3 (
>>"%~4" (
echo %%~H
echo %%~tH
for /f "tokens=* delims=," %%I in ('type "%%~H"') do (
echo %%~I
)
)
)
)
popd
)
)
pause
exit/b

Related

Batch variable store result from command

It seems for me a very simple question, however I am struggling a lot with this and don't find an answer yet.
My aim is to count occurences of a specific string in a file.
I do or try to do this using following command:
for /f "tokens=2 delims=;" %%a in ('path to file with searchstring') do (
set count=('path to file I am searching in' find /c "%%a")
if !count! NEQ 0 echo !count!
)
Seems straightforward for me however the second line seems to be wrong as the script exits.
I want to save the result of findin a var because I only wants to outpout Nonzero resutls.
Here's an example batch-file using findstr, for better word matching, (It uses the filenames from your previous question):
#(For /F "UseBackQTokens=2Delims=;" %%G In ("classID.txt")Do #(Set "count=0"
For /F %%H In ('^""%__AppDir__%findstr.exe" /IN "\<%%G\>" "trc.txt"^"'
)Do #(Set /A count+=1)&SetLocal EnableDelayedExpansion
If !count! Gtr 0 (Echo %%G: !count!)&Endlocal))&Pause
Here it is fully parenthesized over multiple lines for you to better understand:
#Echo Off
For /F "UseBackQ Tokens=2 Delims=;" %%G In (
"classID.txt"
) Do (
Set "count=0"
For /F %%H In (
'^""%__AppDir__%findstr.exe" /I /N "\<%%G\>" "trc.txt"^"'
) Do (
Set /A count +=1
)
SetLocal EnableDelayedExpansion
If !count! Gtr 0 (
Echo %%G: !count!
)
Endlocal
)
Pause
And a fully parenthesized example of it outputting the results to a file named results.txt:
#Echo Off
(
For /F "UseBackQ Tokens=2 Delims=;" %%G In (
"classID.txt"
) Do (
Set "count=0"
For /F %%H In (
'^""%__AppDir__%findstr.exe" /IN "\<%%G\>" "trc.txt"^"'
) Do (
Set /A count +=1
)
SetLocal EnableDelayedExpansion
If !count! Gtr 0 (
Echo %%G: !count!
)
Endlocal
)
)>"results.txt"

Batch file: Deleting folders after for loop

This is what i have right now. If I run this script, loop never ends and run forever.
I tried to delete a folder in kmz folder after moving a file inside kmz folder's folder; however, it wont delete a folder inside the kmz folder. I think this is why my batch file is running forever.
any help??
setlocal enableextensions enabledelayedexpansion
:loop
IF EXIST D:\kmz\*.* (
FOR /f "delims=" %%a IN ('dir /b /s /a-d "D:kmz\*.*" ') do (
FOR %%b IN ("%%~dpa.") do (
REN "%%a" "%%~nb.*"
move %%b\* D:\renamed
del %%b
goto loop2
)
)
)
:loop2
IF EXIST D:\renamed\*.* (
for /R D:\renamed %%G in (*.*) do (
ogr2ogr -f "ESRI Shapefile" "D:\shapefile\%%~nG_boundary.shp" "%%G"
move %%G D:\Photos\%%~nG
goto transfering
)
)
:transfering
IF EXIST D:\shapefile\*.shp (
for /R D:\shapefile %%K in (*.*) do (
set "filename=%%~nK"
set "first5=!filename:~0,5!"
move %%K D:\Photos\!first5!
echo !date!-!time! %%K is created >> D:\Photos\!first5!\log.txt
)
)
goto loop
this is my second try:
setlocal enableextensions enabledelayedexpansion
:loop
FOR /f "delims=" %%a IN ('dir /b /s /a-d "D:kmz\*.*" ') do (
FOR %%b IN ("%%~dpa.") do (
IF EXIST %%a (
REN "%%a" "%%~nb.*"
move %%b\* D:\renamed
rmdir %%~dpa
goto loop2
)
)
)
:loop2
IF EXIST D:\renamed\*.* (
for /R D:\renamed %%G in (*.*) do (
ogr2ogr -f "ESRI Shapefile" "D:\shapefile\%%~nG_boundary.shp" "%%G"
move %%G D:\Photos\%%~nG
goto transfering
)
)
:transfering
IF EXIST D:\shapefile\*.shp (
for /R D:\shapefile %%K in (*.*) do (
set "filename=%%~nK"
set "first5=!filename:~0,5!"
move %%K D:\Photos\!first5!
echo !date!-!time! %%K is created >> D:\Photos\!first5!\log.txt
)
)
goto loop
I was able to delete a folder from D:\kmz, but loops wont stop.
I this this output is the reason...
C:\>FOR /F "delims=" %a IN ('dir /b /s /a-d "D:kmz\*.*" ') do (FOR %b IN ("%~dpa.") do (IF EXIST %a (
REN "%a" "%~nb.*"
move %b\* D:\renamed
rmdir %~dpa
goto loop2
) ) )
File Not Found
To stop your loop, try setting loop as a variable with a value of one, and code it so that every time you run the command it takes away one from loop. Then say if the loop variable equals 0, go to another part which has the directory of your file and the delete command. I hope this works.

Create folder for each file name and move the file

I have batch file that needs to sort csv file based on the first few numbers of the csv file. The files are in one folder and after detecting the first few numbers before the underscore, it should assign and set them a name e.g
C:\FDM\FDMConversion\890_AMMC1_Recording_2012.csv
C:\FDM\FDMConversion\898000_AMMC1_Recording_2012.csv
Basically, I want the script to pick each file and create a folder.
for example, to move 890_AMMC1_Recording_2012.csv, the script will extract 890 and create a folder sample1 and then move the file into sample1.
and to move 898000_AMMC1_Recording_2012.csv the script will extract 898000 and create a folder sample2 and move the file into sample2 folder
Code is below :
set filename="C:\FDM\FDMConversion\*.csv"
for /f %%i in ('dir %filename% /b /a-d ') do (
set "filename=%%~i"
for /f "delims=_ tokens=1" %%a in ('echo !filename!') do (
rem rem set folder=%%a
If "%%a"=="890" (
set sample1=%%a
mkdir "C:\FDM\FDMConversion\!sample1!" 2>nul
for /f "delims=_ tokens=1" %%a in ('echo !filename!') do set ade=%%a
pushd "C:\FDM\FDMConversion"
for /r %%a in ("\!ade!*.csv" ) do (
move /Y "%%a" "C:\FDM\FDMConversion\!ade!\%%~nxa"
)
popd
)
If "%%a"=="898000" (
set sample2=%%a
mkdir "C:\FDM\FDMConversion\!sample2!" 2>nul
for /f "delims=_ tokens=1" %%a in ('echo !filename!') do set ade=%%a
pushd "C:\FDM\FDMConversion"
for /r %%a in ("\!ade!*.csv" ) do (
move /Y "%%a" "C:\FDM\FDMConversion\!ade!\%%~nxa"
)
popD
)
)
echo off
SETLOCAL ENABLEDELAYEDEXPANSION
set filename="C:\FDM\FDMConversion\*.csv"
for /f %%i in ('dir %filename% /b /a-d ') do (
set "filename=%%~i"
for /f "delims=_ tokens=1" %%a in ('echo !filename!') do (
rem rem set folder=%%a
If "%%a"=="890" (
mkdir "C:\FDM\FDMConversion\sample1" 2>nul
for /f "delims=_ tokens=1" %%a in ('echo !filename!') do set ade=%%a
pushd "C:\FDM\FDMConversion"
for /r %%a in ("\!ade!*.csv" ) do (
move /Y "%%a" "C:\FDM\FDMConversion\sample1\%%~nxa"
)
popd
)
If "%%a"=="898000" (
mkdir "C:\FDM\FDMConversion\sample2" 2>nul
for /f "delims=_ tokens=1" %%a in ('echo !filename!') do set ade=%%a
pushd "C:\FDM\FDMConversion"
for /r %%a in ("\!ade!*.csv" ) do (
move /Y "%%a" "C:\FDM\FDMConversion\sample2\%%~nxa"
)
popD
)
)
)

Equalise the number of files with windows batch

I have a script that is designed to count the number of files with a value in the filename (****_1.jpg), compare it with the number of files with another name (****_2.jpg) and delete the larger number of files so the number of files are equal for each type.
This is what I've got so far
#echo off
setlocal enableextensions
set count1=0
set count2=0
for %%f in (.\seq\*_1.jpg) do set /a count1+=1
echo "1 " %count1%
for %%f in (.\seq\*_2.jpg) do set /a count2+=1
echo "2 " %count2%
if %count1% gtr %count2% (
set /a count=%count2%-%count1%
for /l %%A in (1,1,%count%) do echo "%count2% + %%A _1.jpg"
)
if %count2% gtr %count1% (
set /a count=%count2%-%count1%
for /l %%A in (1,1,%count%) do echo "%count1% + %%A _2.jpg"
)
endlocal
I can get the counts, I make it to my if statements and then nothing happens. What am I missing?
For now I'm trying to echo a list of files I'm about to delete.
In addition to the need for ENABLEDELAYEDEXPANSION, there really is no record of file names from either set. The "count" cannot be used to create the filename, can it?
I put in some code at the top to create a test set. Always referencing THEDIR obviates the need to hardcode a directory name in many places.
When you think it will work, remove echo from the DEL command line.
#echo off
setlocal enableextensions enabledelayedexpansion
set "THEDIR=.\seqtest"
if not exist "%THEDIR%" (mkdir "%THEDIR%")
for /l %%i in (1, 1, 5) do (echo %%i >"%THEDIR%\file_%%i_1.jpg")
for /l %%i in (1, 1, 7) do (echo %%i >"%THEDIR%\file_%%i_2.jpg")
set count1=0
set count2=0
for %%f in ("%THEDIR%\*_1.jpg") do set /a count1+=1
echo "1 " %count1%
for %%f in ("%THEDIR%\*_2.jpg") do set /a count2+=1
echo "2 " %count2%
if %count1% gtr %count2% (
set /a count=%count2%-%count1%
set /a "dcount=0"
for /f "usebackq tokens=*" %%f in (`dir /b "%THEDIR%\*_1.jpg"`) do (
echo DEL "%%~f"
set /a "dcount+=1"
if !dcount! EQU !count! (goto Outa2)
)
for /l %%A in (1,1,%count%) do echo "%count2% + %%A _1.jpg"
)
if %count2% gtr %count1% (
set /a count=%count2%-%count1%
set /a "dcount=0"
for /f "usebackq tokens=*" %%f in (`dir /b "%THEDIR%\*_2.jpg"`) do (
echo DEL "%%~f"
set /a "dcount+=1"
if !dcount! EQU !count! (goto Outa2)
)
)
:Outa2
:TheEnd
exit /b 0
If you want to delete any _1 file that does not exist as an _2 file and vice versa, you could loop over the _1 files and delete any for which no _2 file exists. Then, loop over the _2 files and delete any for which no _1 file exists.
for /f "usebackq tokens=*" %%f in (`dir /b "%THEDIR%\*_1.jpg"`) DO (
set "FN=%%~f"
set "BASE=!FN:~0,-6!"
if not exist "%THEDIR%\!BASE!_2.jpg" (echo DEL "%THEDIR%\!BASE!_1.jpg")
)
for /f "usebackq tokens=*" %%f in (`dir /b "%THEDIR%\*_2.jpg"`) DO (
set "FN=%%~f"
set "BASE=!FN:~0,-6!"
if not exist "%THEDIR%\!BASE!_1.jpg" (echo DEL "%THEDIR%\!BASE!_2.jpg")
)
As I understand this problem, you have two lists of files and you want to delete files from the larger list so both lists have the same number of files. Right? For example:
1_1.jpg 1_2.jpg
2_1.jpg 2_2.jpg
3_1.jpg 3_2.jpg
4_2.jpg
5_2.jpg
In previous example you want to delete 4_2.jpg and 5_2.jpg, correct? If the first list is the larger one, the files must be deleted from it; if both lists have the same number of files, no files be deleted. This solution do that:
#echo off
setlocal
rem Enter to the folder with files
cd seq
rem Get the first list of files
dir /B *_1.jpg > first.txt
rem Merge the first list...
< first.txt (
rem ... with the second list
for %%f in (*_2.jpg) (
rem For each file in second list, read a file from first list
set "first=" & set /P "first="
if not defined first ( rem The second list is larger: cut it
ECHO del "%%f"
)
)
rem If still are files in first list, it is larger: cut it
for /F "delims=" %%f in ('findstr "^"') do ECHO del "%%f"
)
I think, Your method for searching for all *.jpg files is little buggy. You should try this following approach instead. I've modified the code to check the code a little - but you'll get the idea.
#echo off
setlocal EnableDelayedExpansion enableextensions
set count1=0
set count2=0
for /f %%f in ('Dir /s /b "Photo\*.jpg"') do set /a count1+=1
echo "1 " %count1%
for /f %%f in ('Dir /s /b "Photo\*.Png"') do set /a count2+=1
echo "2 " %count2%
if %count1% gtr %count2% (
set /a count=%count2%-%count1%
for /l %%A in (1,1,%count%) do echo "!count2! + %%A _1.jpg"
)
if %count2% gtr %count1% (
set /a count=%count2%-%count1%
for /l %%A in (1,1,%count%) do echo "!count1! + %%A _2.jpg"
)
endlocal
pause >nul
You can change the searching path from - "Photo\*.jpg" to anything in both cases. And this one has given me desired result on the CMD. I Hope this will work fine for you.
...
echo "2 " %count2%
set /a count=count1-count2
set "count=%count:-=%"
if %count1% gtr %count2% (
...
You evidently want to calculate count and need a method to find its absolute value.
simply subtract one vale from the other, then replace any - in the result with nothing.
From the prompt, see set /? for documentation.

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