I have a folder MyFolder and it contains 3 sub-folders say A,B and C.
I want to copy those sub-folders which are modified today.
The command for /D %%A in ("D:\MyFolder*") do ( echo **%%~fA )** provides me all 3 sub-folders, now I am calling another loop and passing %%~fA(which is current folder in loop) to get to know is there any modifications made in this folder or not. But I am getting echo off.
set LocalFolder=D:\Backup\1
for /D %%A in ("D:\MyFolder\*") do (
echo %%~fA
for /F %%N in ('forfiles /S /P "%%~fA" /M "*" /D +0 /C "cmd /C if #isdir==FALSE echo _" ^| find /C "_"') do set "NUMBER=%%N"
echo %NUMBER%
if %%N GTR 0 xcopy "%%~fA\*.*" "%LocalFolder%\" /s/e/k/f/c
)
Related
I'm building a menu with this command CHOICE /c 123456789 /N /M "Type your choise"
This is inside a my menu batch script and it calls Tools1.bat it makes everything inside the Tools.bat run with Sub folder reader
IF %ERRORLEVEL% EQU 1 (
#For /F "EOL=? Delims=" %%G In ('Dir /B /S /A:D') Do #PushD "%%G" && (Call "%~dp0Tools1.bat" >NUL 2>&1 & PopD)
)
Tools.bat
ren "asset_database_?_*_?_Release" Asset_Database_Cleaned_0.txt
findstr /i "icon" Asset_Database_Cleaned_0.txt > Asset_Database_Cleaned_1.txt
findstr /i "[(0-9)]" Asset_Database_Cleaned_0.txt > Asset_Database_Cleaned_2.txt
ren "Asset_Database_Cleaned_0.txt" asset_database_9_99_9_Release
ren "%~dp01_Prior_Version\Asset_Database_Cleaned_2.txt" "Prior Version.txt"
ren "%~dp02_Current_Version\Asset_Database_Cleaned_2.txt" "Current Version.txt"
)
I have 2 folders with one file inside each folder
01_Prior_Version
+ -- asset_database_2_09_7_Release
02_Current_Version
+ -- asset_database_3_29_4_Release
the asset_database has random numbers so I use wildcards for that
asset_databaseRelease or asset_database_?__?_Release
These files get renamed to Asset_Database_Cleaned_0.txt
and then I use findstr /i to extract content that I need
I have tried many different ways to add that top script to my menu batch script
I have tried many different ways to add a Sub folder reader using SET & Source etc
IF %ERRORLEVEL% EQU 1 (
#For %%G In ("%~dp01_Prior_Version") Do Set "source=%%~fG"
#For %%G In ("%~dp02_Prior_Version") Do Set "target=%%~fG"
Set "Source1=1_Prior_Version\Asset_Database_Cleaned_1.txt"
Set "Target1=1_Prior_Version\Prior Version.txt"
findstr /i "icon [(0-9)]" %Source1% > %Target1%
ren "Prior\Asset_Database_Cleaned_0.txt" asset_database_9_99_9_Release
I tried using this script, but couldn't put all of that above together
#echo off
FOR /F %%i in ('dir /b/s/a-d') DO (
if "%%~xi" == "" rename "%%~fi" "%%~ni.txt"
)
This is my menu
:Data Finder
echo.
ECHO ################################################################
ECHO ALL YOUR ORIGINAL FILES WILL BE SAVED
ECHO ################################################################
echo.
ECHO Press 1 - Extract Data
ECHO Press 2 - Run PY
echo.
ECHO Thank You
ECHO For all the support
echo.
CHOICE /c 123456789 /N /M "Type your choise"
IF %ERRORLEVEL% EQU 1 (
#For /F "EOL=? Delims=" %%G In ('Dir /B /S /A:D') Do #PushD "%%G" && (Call "%~dp0Tools1.bat" >NUL 2>&1 & PopD)
goto=:Data Finder
)
IF %ERRORLEVEL% EQU 2 (
Call "%~dp0Tools2.py"
goto=:Data Finder
)
When I add this in, the CMD just closes
with the help of batch file I am able to delete files from the main directory and sub directories but I am finding it difficult to delete empty sub directories left after files inside it got deleted . I have written script but it is not working for deleting empty sub directories part
MY Batch Script
#echo off
Set _Extentions=".LOG"
Set _FolderList= "D:\FCS"
Set _FolderList=%_FolderList% "D:\SMSGateway\SMSLogs"
Set _NoOfDays=15
for %%s in (%_FolderList%) do (
for %%d in (%_Extentions%) do (
call :process_Deletion %%s %%d
)
)
:process_Deletion
IF [%1] == [] GOTO EndOfFun
set _ParaPath=%1
set _ParaExtn=%2
echo forfiles /P %_ParaPath% /S /m *%_ParaExtn% /D -%_NoOfDays% /C "cmd /c if #isdir==FALSE echo #path #fdate #ftime"
echo forfiles /P %_ParaPath% /S /m *%_ParaExtn% /D -%_NoOfDays% /C "cmd /c if #isdir==FALSE del #file"
echo for /f "delims=" %%d in ('dir %_FolderList% /s /b /ad ^| sort /r') do rd "%%d"
:EndOfFun
EXIT /B
What am I doing wrong here ? Please help..
Empty directories require rd or rmdir
https://www.computerhope.com/rmdirhlp.htm
The rd and rmdir commands remove empty directories in MS-DOS. To delete directories with files or directories within them, you must use the deltree command. If you are running Microsoft Windows 2000 or Windows XP, use the /S option.
I know someone out there has a nice quick solution for this: I just believe I am missing something. I am slightly new to creating bat files. I have roughly 2,000 files with improper naming on a share drive.
The below bat gets me started but I need to have the new file name include spaces but when I try it gives an invalid syntax command even with the ' " '.
Line 3, 3.MRF, is where it is giving me the syntax error '-' is not a valid command.
#echo
forfiles /S /M "1.PURCHASE*.*" /C "cmd /c rename "1.PURCHASE*.*" "2.PURCHASE*.*""
forfiles /S /M "3.MRF*.*" /C "cmd /c rename "3.MRF*.*" "1.MRF - *.*""
forfiles /S /M "3.ACOMRF-*.*" /C "cmd /c rename "3.ACOMRF-*.*" "1.ACO-MRF-*.*""
forfiles /S /M "2.RECEIPT*.*" /C "cmd /c rename "2.RECEIPT*.*" "3.RECEIPT*.*""
forfiles /S /M "2.RECIEPT*.*" /C "cmd /c rename "2.RECIEPT*.*" "3.RECEIPT*.*""
:exit
#pause
Perhaps run a for loop instead, it just looks much better to start off with:
#echo off
for /r /d %%a in (*) do (
pushd "%%~a"
ren "1.PURCHASE*.*" "2.PURCHASE*.*"
ren "3.MRF*.*" "1.MRF - *.*"
ren "3.ACOMRF-*.*" "1.ACO-MRF-*.*"
ren "2.RECEIPT*.*" "3.RECEIPT*.*"
ren "2.RECIEPT*.*" "3.RECEIPT*.*"
popd
)
Here you need one loop that will pushd to each of the subdirectories, rename anything that matches the rename parameter.
I would suggest using String Manipulation within a simple for-loop.
#echo off
setlocal enabledelayedexpansion
FOR %%A IN (3.MRF*.*) DO (
SET name=%%A
rename "!name!" "!name:3.MRF=1.MRF - !"
)
Before:
3.MRF A.txt
3.MRF B.txt
3.MRF C.txt
After:
1.MRF - A.txt
1.MRF - B.txt
1.MRF - C.txt
Update
Made a more generic solution which lets you define all search and replace strings. Moreover it works on all subdirs now.
#echo off
setlocal EnableDelayedExpansion
PUSHD "%0\.."
REM <search_1>;<replace_1|<search_2>;<replace_2>|...|<search_n>;<replace_n>
SET SearchAndReplace=3.MRF - ~1.MRF - ;3.ACOMRF-~1.ACO-MRF-
REM Replace ; with \n
SET SearchAndReplace=!SearchAndReplace:;=^
!
REM iterate over search and replace tokens
FOR /F "tokens=1,2 delims=~" %%G IN ("!SearchAndReplace!") DO (
set search=%%G
set replace=%%H
FOR /F "usebackq delims=" %%I IN (`dir /S /B /A:-d "*!search!*" 2^>nul`) do (
set file="%%I"
REM hack to allow replace !replace! for !search! in !file!
FOR /F "delims=" %%J IN ("!search!") do (
FOR /F "delims=" %%K IN ("!replace!") do (
echo move !file! !file:%%J=%%K!
move !file! !file:%%J=%%K!
)
)
)
)
POPD
Set the SearchAndReplace variable as needed (see comment).
I would like to create 1 batch file that deletes a type of file (i.e. ".bak") with different date ranges situated in different sub folders that are in the same patent folder, but I can list the minority of folders.
I have managed to create a FOR loop to look in certain directories (which the directories are set in a variable), deleting any '*.bak' file over a certain age with the below script:
SET "WeeklyBAKLocation=Folder20 Folder21 Folder25 Folder28"
SET WeeklyBAK=7
SET DailyBAK=3
FOR %%x IN (%WeeklyBAKLocation%) DO forfiles /p "%%x" /s /m *.bak /d -%WeeklyBAK% /c "cmd /c DEL #path /q"
<SECOND FOR LOOP below HERE>
The above works deleting .bak files older than 7 days in those folders, my question is how can I reverse that and delete '.bak' files in every other directory that's older than 3 days, without deleting the ones kept from the first query?
I tried nesting FOR and FORFILES, using findstr /v to ignore them as below (but it would ignore each directory for that 1 loop, and then delete it for the next loop wouldn't it, so eventually it would not have worked and is massively inefficient?)
SET "WeeklyBAKLocation=Folder20 Folder21 Folder25 Folder28"
SET WeeklyBAK=7
SET DailyBAK=3
<First FOR LOOP above HERE>
FOR %%x IN (%WeeklyBAKLocation%) DO FOR /F "delims=*" %%G IN ('dir /b /s "%~dp0" ^| findstr /v "\%%x"') DO forfiles /p "%%G" /s /m *.bak /d -%DailyBAK% /c "cmd /c ECHO #path /q"
Essentially can I ignore SOME directories at once when walking through them to find .bak files to delete only ones that are 3 days old.
Many thanks in advance.
FOR /F "delims=*" %%G IN (
'dir /b /s /AD "%~dp0" ^| findstr /v "\%%x"') DO (
set "zapme=Y"
FOR %%x IN (%WeeklyBAKLocation%) DO if /i "%%x"=="%%G" set "zapme="
if defined zapme forfiles /p "%%G" /s /m *.bak /d -%DailyBAK% /c "cmd /c ECHO #path /q"
)
read the directory list in basic form (note /ad) and for each directory, set zapme to something then check whether the directory is not to be processed and set zapme to nothing if it's one of those directories. The zapme flag can then be tested for being set or not set. If it's set, go ahead and process the directory.
FOR /F "delims=*" %%G IN (
'dir /b /AD "%sourcedir%"') DO (
set "zapme=Y"
FOR %%x IN (%WeeklyBAKLocation%) DO if /i "%%x"=="%%G" set "zapme="
if defined zapme ECHO forfiles /p "%sourcedir%\%%G" /s /m *.bak /d -%DailyBAK% /c "cmd /c ECHO #path /q"
)
...happens every time I don't actually test it...
I want to write a batch that finds all docs less than 50 mb in c:\ and copy them in a folder but ignore system directory docs. I prefer it does not even search in the system dir.
Here is my batch that finds and copies all files less 50 mb in right directory but i can not make it to ignore system from searching or C:\Windows directory.
#ECHO off
:: variables
SET odrive=%odrive:~0,2%
SET backupcmd=xcopy /s /c /d /e /h /i /r /y
MKDIR "C:\Users\Documents\USBBackups\DOC\C"
forfiles /P C:\ /M *.DOC* /S /C "cmd /c if #fsize leq 50000000 echo #PATH " > "C:\Users\Documents\USBBackups\DOCC.txt"
FOR /F "tokens=*" %%a in (C:\Users\Documents\USBBackups\DOCC.txt) do xcopy %%a "C:\Users\Documents\USBBackups\DOC\C" /c /h /i /r /y
#ECHO off
There is no way to tell forfiles to exclude certain directories when switch /S is provided. You will have to write your own code that does that.
I would not use forfiles for that due to poor performance, but standard for instead:
#echo off
for /D %%D in ("%SystemDrive%\*.*") do (
if /I not "%%D"=="%SystemRoot%" (
pushd "%%D"
for /R %%F in ("*.doc?") do (
if %%~zF LEQ 50000000 (
echo %%F
)
)
popd
)
)
Here the root directory level is enumerated by for /D. All directories other than %SystemRoot% are enumerated recursively by for /R.
I changed the search pattern from *.doc* to *.doc? in order not to include files ending in .doc.lnk for example, which I guess you do not want to be retrieved.
Instead of the echo command you can directly place your xcopy command line with "%%F" provided as the copy source.
You can do the same directly in command prompt as a one-liner, like this:
for /D %D in ("%SystemDrive%\*.*") do #if /I not "%D"=="%SystemRoot%" pushd "%D" & (for /R %F in ("*.doc?") do #if %~zF LEQ 50000000 echo %F) & popd
I recommend not to walk through the entire directory tree and later filtering by something like findstr /V /I /L /B /C:"%SystemRoot%", because in that case you were wasting time enumerating a huge number of items which you ignore afterwards.
However, if you do want to rely on forfiles /S, the working command line looks like this:
2> nul forfiles /S /P "C:\\" /M "*.doc*" /C "cmd /C if #isdir==FALSE if #fsize LEQ 50000000 echo #path" | findstr /V /I /L /B /C:"\"%SystemRoot%"
Adapt this technique of using findstr to filter out certain names.
To see size of folders in Documents, excluding music, video, or pictures folders.
for /f "skip=3 tokens=3" %A in ('Reg query "HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders" /v "Personal"') do set doc=%A
for /f "usebackq tokens=2* delims= " %i IN (`dir "%doc%" /a /s ^|findstr /i /v "\/"^|findstr /l /v "Pictures Music Video"`) DO #echo %j&echo.
However you could start the forfiles command in the c:\users or the particular users home folder (%userprofile%). You specify to start at c:\ which includes all folders.
forfiles /P %userprofile% /M .DOC /S /C "cmd /c if #fsize leq 50000000 echo #PATH "
forfiles /P c:\users /M .DOC /S /C "cmd /c if #fsize leq 50000000 echo #PATH "