creating folders based on Filename without overwriting - batch-file

Working on a script whereby Staff Scans in Students Exams Certificates via Photocopier and it then places a copy to a location
the script below does the following
1) Scans to C:\users\location as filename.pdf (The Staff member will manually enter STudent number at the photocopier and it will save the file name as that)
2) Script then creates folder based on filename so here it will create a folder called /filename
3) Moves the PDF into that folder
it all works fine
however i am trying to modify it so it does not overwrite
so if for example staff member makes a typo of student1 and student1 already exists we dont want to override it
any suggestions
script is as below you can test it
Code:
#echo off
pushd C:\Users\location
for %%F in (*.pdf) do (
2>nul md "%%~nF"
>nul move /y "%%~nF*.*" "%%~nF"
)
popd

You cannot overwrite folder with MD so I suppose you are talking about move operation:
#echo off
pushd C:\Users\location
for %%F in (*.pdf) do (
2>nul md "%%~nF"
echo n|move /-y "%%~nF*.*" "%%~nF" >nul 2>nul
)
popd
or (might depend on local settings and the expected input by move /-y)
#echo off
pushd C:\Users\location
for %%F in (*.pdf) do (
2>nul md "%%~nF"
echo n|move /-y "%%~nF*.*" "%%~nF" 2>&1 |find /i "0 files(s)" >nul 2>nul || (
2>nul md "%%~nF_2"
move "%%~nF_2*.*" "%%~nF_2" >nul 2>nul
)
)
popd

Related

Fix last-but-one space-separated words to move files

I try to move files making with a script their respective folders.Example of desidered and wrong output
To set a substring I use
for %%I in (*.cbr) do (
set "file=%%I"
for %%J in ("!file: =\!") do set "folder=!file: %%~nxJ=!"
For example if I have this filenames
the punisher one.cbr
the punisher two.cbr
the folder name will be the punisher
Problem is when I try to move with another example. If I have 3 files
the punisher beta.cbr
the punisher beta new.cbr
the punisher past.cbr
and I use this command to make directories
mkdir "!folder!" 2>NUL
move /Y "!file!" "!folder!"
But with this example is where I fail and I get unwanted outcome because it creates 3 folders instead of only one (it wrongly also move all files when should be move only 2 files in one folder)
Where is the mistake? I don't understand if is here
for %%J in ("!file: =\!") do set "folder=!file: %%~nxJ=!"
or here
mkdir "!folder!" 2>NUL
move /Y "!file!" "!folder!"
Entire code example is
#echo off
setlocal EnableDelayedExpansion
for %%I in (*.pdf) do (
set "file=%%I"
for %%J in ("!file: =\!") do set "folder=!file: %%~nxJ=!"
mkdir "!folder!" 2>NUL
move /Y "!file!" "!folder!"
echo "!file!" moved to "!folder!"
)

Move files to parent directory if their extension matches the sub-directory extension

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.

Moving text files one by one using batch-file with a timeout

hi guys i'm a trying to move text files one by one with a timeout of 8 seconds from one folder to another using a batch script. i have this script so far;
move /-y "D:\example\original\*2007*.txt" "D:\example\New folder\"
what should i add so that it doesn't move the files at once?
As #npocmaka recommend to you the user confirmation for example like this batch script : Movies wrapper script
#ECHO OFF
SETLOCAL
SET "ROOT=%~dp0"
SET "FORCE=0"
IF /I "%~1"=="/f" (
SET "FORCE=1"
SHIFT
)
IF "%~1"=="" GOTO :END_PARSE
SET "ROOT=%ROOT%%~1\"
:END_PARSE
ECHO -----------------------------------------------
ECHO WRAPPER - "%ROOT%"
ECHO -----------------------------------------------
SET "COUNT_SUCC=0"
SET "COUNT_FAIL=0"
SETLOCAL enabledelayedexpansion
REM Iterates throw the files on this current folder.
FOR %%f IN ("%ROOT%\*.*") DO (
REM Checks if the file isn't the batch file.
IF NOT "%%~ff" == "%~f0" (
IF !FORCE! NEQ 1 (
rem echo force=!Force!
SET /P "INPUT=Do you want to wrap the file "%%~nxf" ? (Y/[N])"
IF /I "!INPUT!"=="Y" (
REM Create a directory as the same name.
IF NOT EXIST "!ROOT!\%%~nf\" MD "!ROOT!%%~nf\">NUL 2>NUL
REM Checks if the directory was created.
REM /Y Suppresses prompting to confirm you want to overwirte an existing destination file.
IF EXIST "!ROOT!%%~nf\" MOVE /y "%%~ff" "!ROOT!%%~nf\">NUL 2>NUL
REM Count files who has been wrapped or not.
ECHO.
IF NOT EXIST "!ROOT!%%~nf\%%~nf%%~xf" (
RMDIR /s /q "!ROOT!\%%~nf\" >NUL 2>NUL
SET /a "COUNT_FAIL+=1"
ECHO The file "%%~nf" hasn't been wrap.
) ELSE (
ECHO The file "%%~nf" has been wrapped.
SET /a "COUNT_SUCC+=1"
)
)
) Else (
REM Checks if the file isn't the batch file.
IF NOT "%%~ff" == "%~f0" (
REM Create a directory as the same name.
IF NOT EXIST "!ROOT!\%%~nf\" MD "!ROOT!%%~nf\"
rem >NUL 2>NUL
REM Checks if the directory was created.
REM /Y Suppresses prompting to confirm you want to overwirte an existing destination file.
IF EXIST "!ROOT!%%~nf\" MOVE /y "%%~ff" "!ROOT!%%~nf\"
rem >NUL 2>NUL
REM Count files who has been wrapped or not.
ECHO.
IF NOT EXIST "!ROOT!%%~nf\%%~nf%%~xf" (
RMDIR /s /q "!ROOT!\%%~nf\" >NUL 2>NUL
SET /a "COUNT_FAIL+=1"
ECHO The file "%%~nf" hasn't been wrap.
) ELSE (
ECHO The file "%%~nf" has been wrapped.
SET /a "COUNT_SUCC+=1"
)
)
)
)
)
ECHO.
SET /a "COUNT_TOT=COUNT_SUCC+COUNT_FAIL"
ECHO Total of %COUNT_TOT% files(s) : %COUNT_SUCC% file(s) wrapped and %COUNT_FAIL% file(s) failed.
ECHO.
PAUSE
use a simple for loop to process each file individually:
for %%a in ("D:\example\original\*2007*.txt") do (
move /-y "%%~fa" "D:\example\New folder\"
timeout /t 8
)
For more information, see for /?

Excluding a folder in a recursive copy in Batch

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

Batch to copy a file to a folder and only ONE subfolder deep

I have this batch file now that copies example.jpg from C:\Temp to the Test-folder and all its subfolders.
I would like it to copy the file only 1 subfolder deep in the Test-folder.
For example copy the picture to Test\subfolder but NOT to Test\subfolder\subfolder2
#echo off
for /r "C:\Temp\Test" %%f in (.) do (
copy "C:\Temp\example.jpg" "%%~ff" > nul
)
PAUSE
Don't use recursion if you want to go only 1 level deep. Try this instead:
#echo off
set src=C:\Temp\example.jpg
set dst=C:\Temp\Test
copy "%src%" "%dst%" >nul
for /d %%d in ("%dst%\*") do (
copy "%src%" "%%~fd" >nul
)
#ECHO OFF
SETLOCAL
SET destroot=c:\temp
FOR /f "delims=" %%i IN ( ' dir /ad/b "%destroot%"' ) DO ECHO COPY "c:\temp\example.jpg" "%destroot%\%%i\"
Simply shows what the batch PROPOSES to do. Remove the ECHO keyword to activate the copy and add >nul to suppress the "copied" message

Resources