How to get file parent parent's folder using batch - for-loop

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

Related

Moving specific number of files into newly created numbered folders

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

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

find multiple files paths with single string

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
::***************************************************************************************

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