I'm trying to combine two FOR loops into one.
Here is my code :
#echo off
SETLOCAL ENABLEDELAYEDEXPANSION
set BackupDest=D:\backup
for /D %%I in ("%HomeDrive%\users\*") do if exist "%BackupDest%\%%~nI\" (
xcopy "%HomeDrive%\users\%%~nI\Desktop" "%BackupDest%\%%~nI\Desktop\" /e /i /y
xcopy "%HomeDrive%\users\%%~nI\Documents" "%BackupDest%\%%~nI\Documents\" /e /i /y
)
for /f "tokens=*" %%I in ('dir /a:d-h /b "%HomeDrive%\users\*" ^| findstr /b /e /i /l /v /g:"%~dp0\bin\exclude_users.txt"') do if not exist "%BackupDest%\%%~nI\" (
echo Destination folder of the user %%~nI is missing
)
I'm note sure if we can do that in this case ?
If yes, how I can achieve this ?
Any help is greatly helpful.
#echo off
setlocal
set "BackupDest=D:\backup"
for /f "tokens=*" %%I in (
'dir /a:d-h /b "%HomeDrive%\users\*" ^| findstr /b /e /i /l /v /g:"%~dp0exclude_user.txt"'
) do (
if exist "%BackupDest%\%%~nxI\" (
xcopy "%HomeDrive%\users\%%~nxI\Desktop" "%BackupDest%\%%~nxI\Desktop\" /e /i /y
xcopy "%HomeDrive%\users\%%~nxI\Documents" "%BackupDest%\%%~nxI\Documents\" /e /i /y
) else (
echo Destination folder of the user %%~nxI is missing
)
)
Use if exist ... (...) else (...) syntax.
A name of a folder uses the modifiers nx, as a folder can be named i.e. firstname.lastname.
If you only use n, then you would only get a part of the folder name firstname.
Related
I am a teacher aid, and my job is to sort student's labs into their folders. The format they turn in their files is like this
lastname_Labname.zip
What I wish to accomplish is to automatically have these zips moved into their folders in a different location. Which follows this format
Lastname1
Lastname2
Lastname3
Finally I would like the zip files to be deleted after.
Here is what I have so far:
To extract the files:
FOR /D /r %%F in ("*") DO (
pushd %CD%
cd %%F
FOR %%X in (*.rar *.zip) DO (
"C:\Program Files\7-zip\7z.exe" x "%%X"
pause
)
popd
)
To sort the files:
#ECHO OFF
SETLOCAL
SET "sourcedir=C:\Something\Something"
SET "destdir=C:Somethign\Something"
FOR /f "delims=" %%a IN (
'dir /b /a-d "%sourcedir%\*.zip" '
) DO (
FOR /f "tokens=1delims=_-" %%b IN ("%%a") DO (
FOR /f "delims=" %%d IN (
'dir /b /ad "%destdir%\*%%b*" '
) DO (
MOVE "%%a" "%destdir%\%%d\"
)
)
)
GOTO :EOF
I would like to combine these functions, and to delete the zips after.
I have a similar setup.
#Echo OFF
set Down=E:\Download
set Extracted=E:\Extracted
for /R "%Down%" %%I in ("*.zip") do (
"%ProgramFiles%\7-Zip\7z.exe" x -y "%%~fI" -pPasswordGoesHere
Del "%%I"
)
FOR %%i IN ("%Down%\*") DO MOVE /Y "%%i" "%Sorted%\%%~nxi" /xf Unzip.bat
FOR /D %%i IN ("%Down%\*") DO ROBOCOPY /MOVE /E "%%i" "%Sorted%\%%~nxi" /xf Unzip.bat
I have a folder with several subfolders. Structure is like:
C:\foo
C:\foo\web.foo
C:\foo\web.bar
C:\foo\win.foo
C:\foo\win.bar
C:\foo\mobile.foo
C:\foo\mobile.bar
I sometimes wish to delete the folders with its containing files with following batch script:
rmdir C:\foo /s /q
Here it didn't matter that the whole folder C:\foo was deleted completely.
But now I only want to delete only the subfolders of C:\foo with its containing files, which DO NOT start with "web.".
Do you have any good solution for this?
The following should do the trick, note it's a batch file using the current directory:
#echo off
for /F "delims=" %%D in ('dir /B /AD ^| findstr /V "^web."') do (
echo rmdir %%D /s /q
)
If it's okay remove the echo in front of rmdir.
The dir command just list directory names because of /AD and use a simple name output because of /B. To search on the beginning use findstr with /V. For negation use ^. Further the pipe symbol needs to be escaped ^|.
If you want a dynamic batch script that uses arguments you can use the following, call it via batchname.bat "C:\foo" web. (if it's okay remove the echo in front of rmdir.):
#echo off
set INVARGS=0
if [%1] == [] set "INVARGS=1"
if [%2] == [] set "INVARGS=1"
if %INVARGS% == 1 (
echo echo %0 ^<directory^> ^<directory_prefix^>
goto eof
)
set "folder=%1%"
set "prefix=%2%"
pushd "%folder%"
echo List of folders that should be deleted:
for /F "delims=" %%D in ('dir /B /AD ^| findstr /v "^%prefix%"') do (
echo "%cd%\%%D"
)
popd
:choice
echo.
set /P "c=Are you sure you want to continue [Y/N]?"
if /I "%c%" EQU "Y" goto yes
if /I "%c%" EQU "N" goto eof
goto :choice
:yes
echo.
pushd "%folder%"
for /F "delims=" %%D in ('dir /B /AD ^| findstr /v "^%prefix%"') do (
echo rmdir %%D /s /q
)
popd
:eof
This will remove all files begin with web.
#echo off
setlocal EnableDelayedExpansion
for /f %%F in ('dir /b /s') do (
set "name=%%~nF"
if /i not "!name:~0,4!" == "web." (
rm !name!
)
)
I want to delete all directories with a specific name. E.g. "vendor"
D:\Data\Project1\Dir\vendor
D:\Data\Project2\AnotherDir\AnotherDir\vendor
D:\Data\Project3\vendor
This is what I have at this moment. This lists all the folders, and subfolders.
for /d %%a in (*) do dir /ad /on /s /b %%a
Now I wish to put one path in a variable, and check whether the directory is equal to a name (for example "vendor"). But I can't find how.
Can you help me?
Regards,
Demian
This is my working solution if you have RimRaf installed:
#ECHO off
setlocal enableDelayedExpansion
:: Folders where the batch program doesn't need to search.
set skipTheseFolders=Decleir Pinokkio
:: All the folders that need to be deleted
set foldersToDelete=vendor node_modules
for /d /r %%d in (*.*) do (
#ECHO %%d
set folder=%%~nxd
set canI="true"
:: For loop to skip folders
for %%s in (%skipTheseFolders%) do (
:: Need to be implemented
set canI="true"
)
IF !canI! =="true" (
for %%l in (%foldersToDelete%) do (
:: If the folder is one of the folders To Delete
IF "!folder!" == "%%l" (
#echo %%d
cd %%d
cd ..
:: Using Rimraf because when you delete node_modules, normal delete won't work
start /B rimraf !folder!
)
)
)
)
The DIR command has an unfortunate limitation that it cannot recursively list specific folder names. The simplest solution is to list all folders, and use FINDSTR to filter out all but the folders that match.
dir /ad /on /s /b | findstr /iec:"\vendor"
Then you simply iterate the results using FOR /F and add your RD command
for /f "eol=: delims=" %%F in
'dir /ad /on /s /b ^| findstr /iec:"\vendor"'
) do rd /s /q "%%F" 2>nul
You can try this :
#Echo OFF
set "Folder=D:\Data"
set "FolderString=vendor"
Setlocal Enabledelayedexpansion
FOR /f "tokens=*" %%F IN ('dir /b /s /ad %Folder%\ ^| find "%FolderString%"') DO (set var="%%F"
ECHO rd /s /q !var! && rd /s /q !var!)
EndLocal
pause
I would like to make a script with Batch. I want from this script to check it out, If a folder contains a file, "list.txt", and if it is in the folder i want to make a copy in an other location. I wrote some lines of code but it's not working. Any ideas?
#echo off
SETLOCAL ENABLEDELAYEDEXPANSION
:loop
for /f %%i in ('dir "C:\Users\ntosis\Desktop\Draft" /ad /o:d /s /b') do (
SET a=%%i
for /R %%a %%t in (*.txt) do if "%%~nxt"=="list.txt" SET p=%%~dpnxt
echo !p!
IF DEFINED %p% ( robocopy C:\Users\ntosis\Desktop\Draft\%a% C:\Users\ntosis\Desktop\Copied\%a% /MOVE /E )
)
echo Folder is empty or does not exist
timeout /t 15
goto loop
The problem in this moment is that the second loop does not the check right.
How about this:
for /f %%i in ('dir "C:\Users\ntosis\Desktop\Draft" /ad /o:d /s /b') do (
IF EXIST "%%i\list.txt" (
robocopy %%i C:\Users\ntosis\Desktop\Copied\ /MOVE /E
)
)
#echo off
setlocal enableextensions disabledelayedexpansion
set "source=C:\Users\ntosis\Desktop\Draft"
set "target=C:\Users\ntosis\Desktop\Copied"
for /l %%t in (0) do (
set "found="
for /d /r "%source%" %%a in (list.txt) do if exist "%%a" (
for %%b in ("%%~dpa.") do (
echo Found "%%a"
robocopy "%%~dpa." "%target%\%%~nxb" /move /e
)
set "found=1"
)
if not defined found (
echo folder is empty or does not exist
)
timeout /t 15
)
I am trying to find all files matching the wildcard *\dev\*\*\*\Results_local.xml in a cmd script, but I failed. I tried:
for %%f in (*\dev\*\*\*\Results_local.xml) do (
echo %%f
)
but it doesn't return any results. What should I do instead?
dir /s/b /a-d Results_local.xml |findstr /i /b /r ".*\\dev\\.*\\.*\\.*\\"
should give you a results list.
for /f "delims=" %%f in (
'dir /s/b /a-d Results_local.xml ^|findstr /i /b /r ".*\\dev\\.*\\.*\\.*\\"'
) do echo %%f
should apply the results to %%f one-by-one.