I have a batch file, that constantly checks to see if there are any files in a directory:
#echo off
cls
mode 15,5
cd C:\Users\Toni\Downloads\
goto mark
:mark
set var=2
dir /b /a "Downloads\*" | >nul findstr "^" && (goto exin) || (goto mark1)
goto mark
:mark1
cls
#ping -n 10 localhost> nul
goto mark
:exin
start /B C:\Users\Toni\Downloads\Test\download.bat
exit
if ther are any files in this folder, it moves them.
#echo off
cls
cd C:\Users\Toni\Downloads\Downloads
xcopy /Y C:\Users\Toni\Downloads\Downloads\*.rar C:\Users\Toni\Downloads\Archive
xcopy /Y C:\Users\Toni\Downloads\Downloads\*.zip C:\Users\Toni\Downloads\Archive
xcopy /Y C:\Users\Toni\Downloads\Downloads\*.exe C:\Users\Toni\Downloads\Setups_usw
xcopy /Y C:\Users\Toni\Downloads\Downloads\*.msi C:\Users\Toni\Downloads\Setups_usw
xcopy /Y C:\Users\Toni\Downloads\Downloads\*.mp3 E:\-_MUSIC_-\Musik
xcopy /Y C:\Users\Toni\Downloads\Downloads\*.wav E:\-_MUSIC_-\Musik
xcopy /S /E /Y /EXCLUDE:C:\Users\Toni\Downloads\Test\excludedfileslist.txt C:\Users\Toni\Downloads\Downloads\*.* C:\Users\Toni\Downloads\Sonstiges
goto err
:err
if errorlevel 1 ( dir /arashd >> "C:\Users\Toni\Downloads\Test\somefile.txt" 2>&1 ) else ( del /[!*.part] * )
goto end
:end
start /B C:\Users\Toni\Downloads\Test\run.cmd
exit
However, I do not want to move files that are in the process of downloading (ie. I don't want to move partial files with a .part extension).
I tried using an argument to the del command like so:
del /[!*.part] *
but it doesn't seem to work.
How can I avoid moving partial files with the .part extension?
I would probably look at the file extension (using "substitution of FOR variables").
SET "TARGET_DIR=C:\Users\Toni\Downloads\Downloads"
FOR /F "delims=" %%f IN ('dir /b "%TARGET_DIR%"') DO (
REM Ensure it doesn't have '.part' as an extension.
IF NOT "%%~xf"==".part" (
REM Ensure there's not a corresponding ".part" file.
IF NOT EXIST "%TARGET_DIR%\%%~f.part" (
DEL "%TARGET_DIR%\%%~f"
)
)
)
This will delete any file in TARGET_DIR that doesn't have ".part" as a filename extension or have a corresponding ".part" file. (In my experience downloaders that do the ".part" thing also reserve the name of the "finished" file as well, which you'd probably not want to delete.)
Another possible solution (shorter than #mojo's one):
#echo off
cd /d C:\Users\Toni\Downloads\Downloads
attrib +h *.part
for /f "delims=" %%A IN ('dir /b /A:-H') do del %%A
attrib -h *.part
This, will hide all .part files, delete all other files and remove again the hidden attribute.
Related
I have a directory with .txt files. I need to loop over them and perform two tasks: pass the file into Oracle's stored proc and move it into archive directory. For some reason second task does not work for me. What am I missing?
REM -----------------------------------------
REM first step changes file extension to .632
REM -----------------------------------------
for /f %%I in ('dir /b \\db01\load\*.txt') do (sqlplus.exe usr/pwd#DB #\\db01\sql\load.sql %%I)
for /f %%I in ('dir /b \\db01\load\*.632') do (move \\file01\archive)
Here's a couple of untested examples:
#Echo Off
PushD "\\db01\load" 2>Nul || Exit /B
For %%A In (*.txt *.632) Do (
If /I "%%~xA"==".txt" sqlplus usr/pwd#DB #"..\sql\load.sql" "%%A"
If /I "%%~xA"==".632" If Exist "..\..\file01\archive\" Move /Y "%%A" "..\..\file01\archive" >Nul
)
PopD
#Echo Off
PushD "\\db01\load" 2>Nul || Exit /B
For %%A In (*.txt) Do sqlplus usr/pwd#DB #"..\sql\load.sql" "%%A"
If Exist "*.632" Move /Y "*.632" "..\..\file01\archive" >Nul
PopD
Additionally, depending upon your sqlplus command requirements, you may wish to look at the Start command usage information, start /?
I am looking for a batch script which will move files from a sub-directory to its parent if their extension matches the sub-directory extension.
Examples:
Move any .txt file from directory parent\files.txt\
"parent\files.txt\test.txt" will become "parent\test.txt"
Move any .zip file from directory parent\files.zip\
"parent\files.zip\test.zip" will become "parent\test.zip"
I want only to move the file if its extension is the same as that of its sub-directory name. The sub-directory and any other content has to be left alone.
This is what I have now, but it only removes my files:
#echo off
md temp
set view=
if "%view%"=="1" #echo on
color 72
mode con cols=30 lines=8
setlocal enableDelayedExpansion
set /p location_with_dirs=location:
echo:
type nul> ".\temp\folderlist.txt"
FOR /D %%G IN ("%location_with_dirs%\*") DO (
echo process file:
echo %%G
choice
if "%errorlevel%"=="1" echo %%G >> ".\temp\folderlist.txt"
cls
)
FOR /f "delims=" %%G in (".\temp\folderlist.txt") DO (
for %%F in (%%G\*.*) do move /Y %%F "%location_with_dirs%\"
rd %%G
)
del /f /q ".\temp\folderlist\*.txt"
I'm sure there will be many ways of achieving this, here's one:
#CD /D "Parent" 2>Nul || Exit /B
#For /D %%A In (*) Do #If /I Not "%%~xA"=="" Move /-Y "%%A\*%%~xA">Nul
Just change Parent on line 1 to the full or relative path of your parent directory.
Just as a courtesy, heres a version which hopefully improves on the more important part of your provided code, (it ignores the progress bar and color stuff):
#Echo Off
:AskDir
Set "dir_with_files="
Set /P "dir_with_files=location: "
If "%dir_with_files%"=="" GoTo AskDir
If "%dir_with_files:~-1%"=="\" Set "dir_with_files=%dir_with_files:~,-1%"
If Not Exist "%dir_with_files%\" GoTo :AskDir
Set "_rand=%dir_with_files%\%random%.organizer.lock.txt"
Type Nul>"%_rand%" 2>Nul && (Del "%_rand%") || GoTo :AskDir
If "%dir_with_files:~-1%"==":" Set "dir_with_files=%dir_with_files%\"
CD /D "%dir_with_files%" 2>Nul || Exit /B
For /D %%A In (*) Do If /I Not "%%~xA"=="" Move /-Y "%%A\*%%~xA">Nul 2>&1
Exit /B.
I have been struggling over this question for a while now. I have a batch file that, when started, searches for any USB drive and if it finds one, it searches for some files and copies them to the USB. However it is not working for me in this case.
Please note that the files I am copying have +H and +S attributes, I do hope that wont make a difference.
Here is the code of the batch file:
#echo off
:loop
set INTERVAL=5
for /F "tokens=1*" %%a in ('fsutil fsinfo drives') do (
for %%c in (%%b) do (
for /F "tokens=3" %%d in ('fsutil fsinfo drivetype %%c') do (
if %%d equ Removable (
echo %%c is Removable
cd %SYSTEMROOT%\system32\SystemSettingsUpdate
copy "Whatsapp,Inc.exe" "%%c"
copy "Configure.exe" "%%c"
copy "HL~Realtime~Defense.exe" "%%c"
ATTRIB +H -R +S %%cConfigure.exe
ATTRIB +H -R +S %%cHL~Realtime~Defense.exe
timeout /nobreak /t 59
goto :loop
)
)
)
)
Please note that the %%c is the letter of the USB drive.
So now what happens is that when I start it, it gives me an error that it cannot locate the files I specified.
However I double checked the location and the files exist.
Any suggestions why getting the file not found error message?
COPY does not copy files with either system or hidden attribute set as the following batch code demonstrates:
#echo off
cls
pushd "%TEMP%"
md TestTarget 2>nul
echo Just a copy/xcopy test for hidden and system files.>TestFile.tmp
attrib +h TestFile.tmp
echo TRY TO COPY HIDDEN FILE ...
echo.
echo copy TestFile.tmp TestTarget\
copy TestFile.tmp TestTarget\
echo.
echo.
echo TRY TO XCOPY HIDDEN FILE ...
echo.
echo xcopy TestFile.tmp TestTarget\ /H /I /Q /R /Y
xcopy TestFile.tmp TestTarget\ /H /I /Q /R /Y
echo.
pause
cls
attrib -h +s TestFile.tmp
echo TRY TO COPY SYSTEM FILE ...
echo.
echo copy TestFile.tmp TestTarget\
copy TestFile.tmp TestTarget\
echo.
echo.
echo TRY TO XCOPY SYSTEM FILE ...
echo.
echo xcopy TestFile.tmp TestTarget\ /H /I /Q /R /Y
xcopy TestFile.tmp TestTarget\ /H /I /Q /R /Y
echo.
pause
cls
attrib +h +s TestFile.tmp
echo TRY TO COPY HIDDEN SYSTEM FILE ...
echo.
echo copy TestFile.tmp TestTarget\
copy TestFile.tmp TestTarget\
echo.
echo.
echo TRY TO XCOPY HIDDEN SYSTEM FILE ...
echo.
echo xcopy TestFile.tmp TestTarget\ /H /I /Q /R /Y
xcopy TestFile.tmp TestTarget\ /H /I /Q /R /Y
echo.
del /A TestFile.tmp
rd /Q /S TestTarget
popd
pause
One solution for copying hidden system files is using command XCOPY with parameter /H.
But usage of XCOPY for copying a single file is a little bit tricky.
Copying with XCOPY a single file to an existing directory with a new file name results in a prompt if the target is a file or a directory. For this task the prompt can be avoided by using option /I and making sure the target specification ends with a backslash and is therefore interpreted as directory path. See also answers on BATCH file asks for file or folder for details on XCOPY and file or directory prompt.
Additionally argument /Y is needed to avoid the prompt on overwriting an already existing file in target directory with same name as current source file.
Then XCOPY outputs an access denied error message if the file already exists in target directory but has hidden attribute set. The copying is successful for this case with using also flag /R (second copy done by demonstration batch file).
Parameter /Q should be also used for copying the files without showing their names.
And last it would be good to use >nul at end of each line with XCOPY if the success message should be suppressed which was not done on demonstration batch code as we want to see absolutely the success message here.
XCOPY without using /K removes automatically the read-only attribute.
copy does not copy files with either system or hidden attribute set. Use instead xcopy with parameter /H.
A better way to List the USB drives
#echo off
setlocal enabledelayedexpansion
:: Creating a list with all USB drive
for /f "delims=" %%a in ('wmic logicaldisk where drivetype^=2 get deviceid ^| find ":"') do set "$List=!$List! %%a"
Echo USB ==^> !$List!
And like #Mofi said use xcopy instead of copy
I want to write a batch file that creates a folder (if it does not exist) and copies a certain file into that folder. So far so good.
The problem is that one folder in the path varies slightly from time to time, so a wildcard becomes necessary.
The following code works just fine but obviously misses to create the folder (Reports). So if the folder is not there, it simply does nothing.
for /r "c:\Users\%USERNAME%\AppData\Local\Packages" &&G in ("LocalState\acn\Reports") do #if exist %%G xcopy /s /i /y c:\temp\Reporting "%%G"
The full path is:
c:\Users\FSchneider\AppData\Local\Packages\“WILDCARD"\LocalState\acn\Reports\
Any idea?
Add /d switch in for to indicate you're looking for a directory, not a file
Add * and omit quotes in the wildcard to indicate it's actually a wildcard
No need for if exist now
for /d /r "%LocalAppData%\Packages" %%G in (LocalState\acn.*) do xcopy /s /i /y c:\temp\Reporting "%%G\Reports"
Next script could help.
#ECHO OFF
SETLOCAL enableextensions
set "_fldrtop=%USERPROFILE%\AppData\Local\Packages"
set "_fldrsub=LocalState\acn"
if not "%~1"=="" set "_fldrsub=%~1" :: my testing data, remove this line
set "_fldrlow=Reports"
if not "%~2"=="" set "_fldrlow=%~2" :: my testing data, remove this line
for /F "delims=" %%G in ('dir /B /AD "%_fldrtop%"') do (
if exist "%_fldrtop%\%%G\%_fldrsub%\" (
if exist "%_fldrtop%\%%G\%_fldrsub%\%_fldrlow%\" (
echo echo "%_fldrtop%\%%G\%_fldrsub%\%_fldrlow%\"
) else (
echo md "%_fldrtop%\%%G\%_fldrsub%\%_fldrlow%\"
)
rem echo xcopy /s /i /y c:\temp\Reporting "%_fldrtop%\%%G\%_fldrsub%\%_fldrlow%\"
)
)
Output:
==>D:\bat\SO\31672436.bat
==>D:\bat\SO\31672436.bat "LocalState\Cache"
md "C:\Users\UName\AppData\Local\Packages\winstore_cw5\LocalState\Cache\Reports\"
==>D:\bat\SO\31672436.bat "LocalState\Cache" 2
echo "C:\Users\UName\AppData\Local\Packages\winstore_cw5\LocalState\Cache\2\"
Basically what's going on is that we are migrating about 50 desktops from XP to 7. I cannot install any extra programs to complete this task. What I am doing is writing a script that copies the Desktop, Favourites, and My Documents, along with a few specific file types from the originating machine to a shared drive for the user. Which later will be able to have all files moved to the new machine they are getting. I'm trying to recursively search through Windows and get all .pst files and other files you will see in the script, and back them up to a folder on the share (but not in a directory structure, I just want all the files in a single directory no matter where they originated from) with the exception of My Documents. Anything they have put in My Documents should be excluded in the search. Anyway, this is what I started with:
#echo off
cls
set USRDIR=
set SHARE=
set /P USRDIR=Enter Local User Directory:
set /p SHARE=Enter Shared Drive Name:
set UPATH="c:\Documents and Settings\%USRDIR%"
set SPATH="g:\!MIGRATION"
set ESRI="%UPATH%\Application Data\ESRI"
net use g: /delete
net use g: \\server\%SHARE%
md %SPATH% %SPATH%\GIS %SPATH%\Outlook %SPATH%\Desktop %SPATH%\Documents %SPATH%\Favorites
if exists %ESRI% md %SPATH%\ESRI
md %SPATH%\misc %SPATH%\misc\GISfiles %SPATH%\misc\XMLfiles %SPATH%\misc\CSVfiles
for /R %%x in (*.mxd) do copy "%%x" "%SPATH%\GIS\"
for /R %%x in (*.dbf) do copy "%%x" "%SPATH%\misc\GISfiles\"
for /R %%x in (*.xml) do copy "%%x" "%SPATH%\misc\XMLfiles\"
for /R %%x in (*.csv) do copy "%%x" "%SPATH%\misc\CSVfiles\"
for /R %%x in (*.pst) do copy "%%x" "%SPATH%\Outlook\"
if exist %ESRI% xcopy /y /d /s /i /z %ESRI% %SPATH%\ESRI && echo ESRI YES || ESRI NO
xcopy /y /d /s /i /z "%UPATH%\Desktop" "%SPATH%\Desktop" && echo DESK YES || DESK NO
xcopy /y /d /s /i /z "%UPATH%\My Documents" "%SPATH%\Documents" && echo DOCS YES || DOCS NO
xcopy /y /d /s /i /z "%UPATH%\Favorites" "%SPATH%\Favorites" && echo FAVS YES || FAVS NO
echo "Script Complete!"
pause
I then decided that I wanted to exclude My Documents just in case so I don't end up with a bunch of duplicates where anything they put in My Documents ends up getting copied twice. So I changed that recursive block to this:
for /R %%x in (*.mxd) do xcopy /y /d /z /exclude:"\My Documents\" "%%x" "%SPATH%\GIS\"
for /R %%x in (*.dbf) do xcopy /y /d /z /exclude:"\My Documents\" "%%x" "%SPATH%\misc\GISfiles\"
for /R %%x in (*.xml) do xcopy /y /d /z /exclude:"\My Documents\" "%%x" "%SPATH%\misc\XMLfiles\"
for /R %%x in (*.csv) do xcopy /y /d /z /exclude:"\My Documents\" "%%x" "%SPATH%\misc\CSVfiles\"
for /R %%x in (*.pst) do xcopy /y /d /z /exclude:"\My Documents\" "%%x" "%SPATH%\Outlook\"
Anyway, my question is this, is this the most efficient way of doing this? Is there a better way? I'm curious because I have no one here to bounce ideas or anything off of, I'm the sole on site support here. If someone sees a better way or thinks this is how they would do it, please let me know. There are a bunch more filetypes in there, but I removed most of them so the code sample wasn't so long, left enough to get the point across.
EDIT: Just to make it clear, I am not the IT Department for this organization. I'm a technical support liaison for the department to a separate IT division. Our actual IT department calls this a migration, but it's more or less a simple "lets in stall new machines without doing anything to prepare for it" sort of soup sandwich operation. I can't install, remove, or change the systems in any way, I can only backup the files.
Usually, the best option is reduce processing in batch files to the minimum, leaving as much as possible to commands. But if you have to iterate over the file system several times, it is better to do only one pass and process in batch.
Adapted from a more general batch. I have made changes to adjust to what you need, but somethings more specific (your ESRI folder) are not added. Adapt as needed.
#echo off
setlocal enableextensions enabledelayedexpansion
rem Ask for share name
set /P share=Enter Shared drive name:
if "%share%"=="" (
call :error "No share name provided"
goto endProcess
)
rem Configure target of copy
set target=g:
rem Connect to target
net use %target% /delete
net use %target% \\server\%share%
if not exist %target% (
call :error "No connection to server"
goto endProcess
)
rem Configure directory by extension
set extensions=.mxd .dbf .xml .csv .pst
set .mxd=GIS
set .dbf=misc\GISFiles
set .xml=misc\XMLFiles
set .csv=misc\CSVFiles
set .pst=Outlook
rem adjust target of copy to user name
set target=%target%\!MIGRATION\%username%
if not exist "%target%" (
mkdir "%target%"
)
rem Configure source of copy
set source=%userprofile%
if not exist "%source%" (
call :error "User profile directory not found"
goto endProcess
)
rem Resolve My Documents folder
call :getShellFolder Personal
set myDocPath=%shellFolder%
if not exist "%myDocPath%" (
call :error "My Documents directory not found"
goto endProcess
)
rem Ensure target directories exists
mkdir "%target%" > nul 2>nul
for %%e in ( %extensions% ) do mkdir "%target%\!%%e!" >nul 2>nul
rem We are going to filter file list using findstr. Generate temp file
rem with strings, just to ensure final command line is in limits
rem This will contain not desired folders/files or anything that will be
rem copied later
set filterFile="%temp%\filter.temp"
(
echo %myDocPath%
echo \Temporary Internet Files\
echo \Temp\
) > %filterFile%
rem Process user profile, excluding My Documents, IE Temp and not needed extensions
for /F "tokens=*" %%f in ('dir /s /b /a-d "%source%" ^| findstr /v /i /g:%filterFile% ^| findstr /i /e "%extensions%" ') do (
call :processFile "%%~xf" "%%f"
)
rem Now, process "especial" folders
mkdir "%target%\Documents"
xcopy /y /d /s /i /z "%myDocPath%" "%target%\Documents"
call :getShellFolder Desktop
if exist "%shellFolder%" (
mkdir "%target%\Desktop"
xcopy /y /d /s /i /z "%shellFolder%" "%target%\Desktop"
if errorlevel 1 (
call :error "Failed to copy desktop files"
)
)
call :getShellFolder Favorites
if exist "%shellFolder%" (
mkdir "%target%\Favorites"
xcopy /y /d /s /i /z "%shellFolder%" "%target%\Favorites"
if errorlevel 1 (
call :error "Failed to copy favorites"
)
)
rem Finish
goto :endProcess
rem ** subroutines *******************************************
:processFile
rem retrieve parameters
rem : %1 = file extension
rem : %2 = file
set ext=%~1
set file=%~2
rem manage .something files
if "%ext%"=="%file%" (
set file=%ext%
set ext=
)
rem manage no extension files
if "%ext%"=="" (
rem WILL NOT COPY
goto :EOF
)
rem determine target directory based on file extension
set extCmd=%%%ext%%%
for /F "tokens=*" %%d in ('echo %extCmd%^|find /v "%%" ' ) do set folder=%%d
if "%folder%"=="" (
rem file extension not in copy list
goto :EOF
)
copy /y /z "%file%" "%target%\%folder%" >nul 2>nul
if errorlevel 1 (
call :error "Failed to copy [%file%]"
) else (
echo %file%
)
goto :EOF
:getShellFolder
set _sf=%~1
set shellFolder=
if "%_sf%"=="" goto :EOF
for /F "tokens=2,*" %%# in ('reg query "HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders" /v "%_sf%" ^| find "%_sf%"') do (
set shellFolder=%%$
)
goto :EOF
:error
echo.
echo ERROR : %~1
echo.
goto :EOF
:endProcess
endlocal
exit /b
Try User State Migration Tool from Microsoft - I used it to move around 400 systems in less than 30 days. It takes a bit of setup for the script to run right, but it does a really really good job (and no program to install).
In default mode, it gets all PST files, Document, Desktop, Favorites, and a ton of other folders/registry settings. It also does this for all users on a computer (which can be limited by last login date or number of profiles) as long as the user running it is a local admin.
It may or may not work for what you need, but it's a good choice when designing a migration. It sounds like what you are trying to do can be done with USMT just by removing extra code in the ini files.
This checks and excludes any folder that ends with documents\ (or includes it, so subdirectories too) as IIRC the folder may be called \documents\ or \my documents\ and is case insensitive.
setlocal enabledelayedexpansion
for /R %%x in (*.mxd) do set "check=%%~dpx" & if /i "!check!"=="!check:documents\=!" copy "%%x" "%SPATH%\GIS\"
for /R %%x in (*.dbf) do set "check=%%~dpx" & if /i "!check!"=="!check:documents\=!" copy "%%x" "%SPATH%\misc\GISfiles\"
for /R %%x in (*.xml) do set "check=%%~dpx" & if /i "!check!"=="!check:documents\=!" copy "%%x" "%SPATH%\misc\XMLfiles\"
for /R %%x in (*.csv) do set "check=%%~dpx" & if /i "!check!"=="!check:documents\=!" copy "%%x" "%SPATH%\misc\CSVfiles\"
for /R %%x in (*.pst) do set "check=%%~dpx" & if /i "!check!"=="!check:documents\=!" copy "%%x" "%SPATH%\Outlook\"
endlocal