Moving specific number of files into newly created numbered folders - windows

I currently have around 550 files in a folder with the same format (.csv) and same headers (all started with the letters "YL").
I wonder if there is a way to splits these files (50 files at a time) (order doesn't matter) into numbered folders? (ex. 1, 2, 3, 4, 5) And also create a subsequent folder for the leftover files?
I have found this scripts and tried to modify it for 50 files, but it looks like it only created a the first folder (subdir1)
#echo off
set /a counter=1
set /a filesperfolder=50
cd dir\dir_main
:loopstart
set dirname=subdir%counter%
md %dirname%
echo %dirname%
dir /b | findstr /v /i "subdir*"> %temp%\temp.txt && for /l %%l in (1,1,%filesperfolder%) do #for /f "tokens=1,2* delims=:" %%a in ('findstr /n /r "^" %temp%\temp.txt ^| findstr /r "^%%l:"') do #move %%b %dirname%\%%b >nul
set /a counter=%counter%+1
for /f "tokens=*" %%a in ('type %temp%\temp.txt ^| find /c /v ""') do set _filesmoved=%%a
del %temp%\temp.txt
IF %_filesmoved% LSS 50 goto done
goto loopstart
:done
cls
echo All files were moved!!
pause
exit

I disliked the script you found as it was hard to read and used a temp file to keep track of the list of files. (Also, it evidently doesn't work, so there's that.)
#echo off
SET /a cnt=50
SET /a fnum=0
FOR /F "delims=" %%f IN ('dir /b /a-d *.csv') DO (
CALL :moveFile "%%f"
)
GOTO :end
:moveFile
IF "%cnt%" equ "50" CALL :makeDir
move "%~1" "%fnum%\%~1"
SET /a cnt+=1
GOTO :EOF
:makeDir
SET /a fnum+=1
mkdir %fnum%
SET /a cnt=0
GOTO :EOF
:end

Here is another way to do it. We test if there are still files in the directory, if there is, create a new directory and copy 50 files.
#echo off & setlocal enabledelayedexpansion
set fold_cnt=1
:test
set file_cnt=50
dir /a-d YL*.csv | findstr /IRC:"File(s)"
if %errorlevel% equ 0 (
mkdir !fold_cnt!
) else (
goto :eof
)
for %%i in (YL*.csv) do (
if not !file_cnt! equ 0 (
set /a file_cnt-=1
move /Y "%%i" "!fold_cnt!\%%i"
)
)
set /a fold_cnt+=1
goto test

Related

How to get file parent parent's folder using batch

Im using batch below to generate a CSV report from multiple .LOG files in 3 Station folders. The code works perfectly to generate report but I want parent folder (Station number folder not the TAG folder) in the report too.
Batch file located at:
C:\Users\amein\Google Drive\Report BACKUP
LOG file path:
C:\Users\amein\Google Drive\Report BACKUP\Station1\TAG\10092019.LOG
C:\Users\amein\Google Drive\Report BACKUP\Station2\TAG\10092019.LOG
C:\Users\amein\Google Drive\Report BACKUP\Station3\TAG\10092019.LOG
#echo off
cls
setlocal EnableDelayedExpansion
set /a total=0
type NUL>"Report.csv"
(
for /R "C:\Users\amein\Google Drive\Report BACKUP\" %%f in (*.LOG) do (
for /f %%a in ('type "%%f"^|find /C /v "" ') do set /a total+=%%a&echo %%f , %%~nf , %%a
)
echo total , !total!
)>>"Report.csv"
GOTO :EOF
edit: SOLVED
#echo off
cls
setlocal EnableDelayedExpansion
set /a total=0
type NUL>Report.csv
(
echo Station Number,Date ,Done
for /R "%userprofile%\Google Drive\Report BACKUP\" %%G in (*.LOG) do (
for %%b in ("%%~dpG\.\..") do set station= %%~nxb
for /f %%a in ('type "%%G"^|find /C /v "" ') do set /a total+=%%a&echo !station!,%%~nG ,%%a
)
echo ,TOTAL ,!total!
)>>Report.csv
GOTO :EOF
Is it possible? I want the report in CSV only show the station number instead of full path
Station 1 10092019 100
#echo off
cls
setlocal EnableDelayedExpansion
set /a total=0
type NUL>Report.csv
(
echo Station Number,Date ,Done
for /R "%userprofile%\Google Drive\Report BACKUP\" %%G in (*.LOG) do (
for %%b in ("%%~dpG\.\..") do set station= %%~nxb
for /f %%a in ('type "%%G"^|find /C /v "" ') do set /a total+=%%a&echo !station!,%%~nG ,%%a
)
echo ,TOTAL ,!total!
)>>Report.csv
GOTO :EOF

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
)

File count and size of each folder

I have the following batch script which gives the size of each folder in a directory. I need help in tweaking this or creating a new script so it gives the file count of each folders as well:
#echo off
setlocal disabledelayedexpansion
set "folder=%~1"
if not defined folder set "folder=%cd%"
for /d %%a in ("%folder%\*") do (
set "size=0"
for /f "tokens=3,5" %%b in ('dir /-c /a /w /s "%%~fa\*" 2^>nul ^| findstr /b /c:" "') do if "%%~c"=="" set "size=%%~b"
setlocal enabledelayedexpansion
echo(%%~nxa # !size!
endlocal
)
endlocal
All the information is already in the output of the inner dir command, you only need to change what to retrieve
#echo off
setlocal disabledelayedexpansion
for %%a in ("%~f1.") do set "folder=%%~fa"
for /d %%f in ("%folder%\*") do (
set /a "size=0", "files=0", "directories=0"
for /f "tokens=1,3,5" %%a in ('
dir /-c /a /w /s "%%~ff\*" 2^>nul ^| findstr /b /c:" "
') do if "%%~c"=="" (
set "files=%%~a"
set "size=%%~b"
) else set /a "directories=%%~a/3"
setlocal enabledelayedexpansion
echo(%%~nxf # !size! bytes : !files! files : !directories! directories
endlocal
)
Add this cmd at the end and it will count files in a given dir
setlocal enableextensions
set count=0
for %%x in ("%folder%\*") do set /a count+=1
echo %count%
endlocal
This is inefficient tho, as you are traversing the whole directory twice.
Ideally, you need to combine the two FOR loops into one, just scan the dir once and add the size to the size counter and do count+=1 for each.
Try something like *added spacing to show what i added
set "folder=%~1"
if not defined folder set "folder=%cd%"
set count=0
for /d %%a in ("%folder%\*") do (
set "size=0"
for /f "tokens=3,5" %%b in ('dir /-c /a /w /s "%%~fa\*" 2^>nul ^| findstr /b /c:" "') do if "%%~c"=="" set "size=%%~b"
set /a count+=1
setlocal enabledelayedexpansion
echo(%%~nxa # !size!
endlocal
)
echo %count%
endlocal

How to test if a Zip file is valid in a windows batch file

I am using the command line version of 7-zip and I can use this to test if a zip file is valid by using the t command.
But I'm trying to create a batch file which will cycle through a bunch of zip files in a directory and do one thing if the zip is empty, and another thing if the zip has some files archived in it.
Any pointers how you do this using a batch file?
this may help
#echo off
setlocal enabledelayedexpansion
set "zipPath=C:\temporal\"
set "zipProg=C:\Program Files (x86)\7-Zip\7z.exe"
call:shortIt "%zipPath%", zipPath
call:shortIt "%zipProg%", zipProg
pushd %zipPath%
for /F "tokens=*" %%a in ('dir /b "%zipPath%" ^| find ".zip"') do (
set/a numFiles=0, isOk=0, size=0, compressed=0
for /F "tokens=*" %%i in ('%zipProg% t "%zipPath%%%a"') do (
echo %%i | find /I "ok" >NUL && set/a isOK=1
echo %%i | find /I "files" >NUL && for /F "tokens=2 delims=:" %%n in ("%%i") do set/a numFiles=%%n
echo %%i | find /I "size" >NUL && for /F "tokens=2 delims=:" %%n in ("%%i") do set/a size=%%n
echo %%i | find /I "compressed" >NUL && for /F "tokens=2 delims=:" %%n in ("%%i") do set/a compressed=%%n
)
if !isOk! neq 0 if !numFiles! equ 0 if !size! neq 0 set/a numFiles=1
if !isOk! equ 0 (
echo(
echo(%zipPath%%%a is not an archive or an error ocurred
echo(
) else (
if !numFiles! neq 0 (
echo(%zipPath%%%a contains !numFiles! files [!size! to !compressed!]
) else (
echo(%zipPath%%%a is empty
)
)
)
popd
endlocal
exit/B 0
:shortIt
SetLocal & set "token=%~s1"
EndLocal & set "%2=%token%"

Comparing the number of files in two folders

I want to verify that two folders have the same number of files.
For example if there are 5 files in folder c:\Users\abc\INBOX, I want to verify that there are also 5 files in folder c:\Users\abc\OUTBOX
How can I achieve this?
#echo off
setlocal enableextensions disabledelayedexpansion
call :getNumberOfFilesInFolderList nINBOX "c:\Users\abc\INBOX"
call :getNumberOfFilesInFolderList nFiles "c:\Users\abc\OUTBOX" "c:\Users\abc\OUTBOX\PROC" "c:\Users\abc\OUTBOX\PEND"
if %nINBOX% EQU %nFiles% (
echo SAME number of files
) else (
echo DIFFERENT number of files
)
endlocal
exit /b
:getNumberOfFilesInFolderList variable folder1 [[folder2] ... ]
setlocal enableextensions disabledelayedexpansion
set "variable="
set /a "total=0"
for %%a in (%*) do if not defined variable (set "variable=%%~a" ) else (
for /f %%b in ('dir /a-d "%%~a" 2^>nul ^| findstr /r /c:"^[ ][ ][ ]*[0-9]"') do set /a "total+=%%b"
)
endlocal & set "%~1=%total%" & echo %total%
goto :eof
This should compare two folders.
#echo off
set aa=0&set bb=0
for %%a in ("c:\Users\abc\INBOX\*") do set /a aa+=1
for %%a in ("c:\Users\abc\OUTBOX\*") do set /a bb+=1
if %aa% EQU %bb% (
echo they have the same number of visible files.
) else (
echo the file count is different
)
TRy something like this :
#echo off
set $Folder1="c:\Users\abc\INBOX"
set $folder2="c:\Users\abc\OUTBOX"
set $count=1
setlocal EnableDelayedExpansion
for %%x in (%$Folder1% %$Folder2%) do (
for /f "tokens=1 delims= " %%a in ('dir %%x ^| find /i "File(s)"') do (
set $Total!$Count!=%%a)
set /a $Count+=1)
If %$Total1% Equ %$Total2% (echo Same number of files) else (echo Different number of files)
If your system is not in english you have to change the "File" according with your system language (ie: "Fichier(s)' in French)
EDIT :
To compare more Directory with the FIRST ONE :
#echo off
set $Folder1="c:\Users\abc\INBOX"
set $folder2="c:\Users\abc\OUTBOX"
set $Folder3=c:\Users\abc\OUTBOX\PROC
set $Folder4=c:\Users\abc\OUTBOX\PEND
set $Count=0
setlocal EnableDelayedExpansion
for %%x in (%$Folder1% %$Folder2% %$Folder3% %$Folder4%) do (
for /f "tokens=1 delims= " %%a in ('dir %%x /a-d ^| find /i "File(s)"') do (
call:test %%x %%a
if !$count! Equ 0 set $Ref=%%a
set $Count=1))
exit/b
:test
if !$count! Equ 1 (
If "%$Ref%" Equ "%2" (echo %$Folder1% SAME %1) else (echo %$Folder1% DIFFERENT %1))

Resources