I created a .bat that will copy pdf file in specified server. The folder structure of file is like this :
\\server\
'----010000-0000\
'----010000-0000-0705-1\
'-------010000-0000-DATA.pdf
'----010000-0000-0705-2\
'-------010000-0000-DATA.pdf
010000-0000 is the code that the user will input. Then batch will search with the exact folder with the code as filename and must copy the pdf file..
My problem is the folder before the pdf file is always has a 4 random numbers which is 0705 (as an example). What I was thinking is to pass through that folder what ever the 4 random numbers value will be. To copy the pdf file
for example (if would do a static code, it will be like this) :
set /p code=Input Control Number:
goto FILE
:FILE
set VER=0
:FILE1
set /a VER +=1
if exist "%fp%\%CODE%\%CODE%-0705-%VER%\%CODE%-DATA.pdf" goto FPCOPY
IF NOT EXIST ELSE GOTO FILE1
:FPCOPY
xcopy "%fp%\%CODE%\%CODE%-0705-%VER%\%CODE%-DATA.pdf" "%HOMEPATH%\Desktop\Backup\%CODE%\" /D /E /C /I /Y /H
start "" "%HOMEPATH%\Desktop\Backup\%code%"
It will surely copy the data. But as I said that 4 digit numbers is always random.
What I have tried is this one (I only replace the 4 digit no. by an *) :
set /p code=Input Control Number:
goto FILE
:FILE
set VER=0
:FILE1
set /a VER +=1
if exist "%fp%\%CODE%\%CODE%-*-%VER%\%CODE%-DATA.pdf" goto FPCOPY
IF NOT EXIST ELSE GOTO FILE1
:FPCOPY
xcopy "%fp%\%CODE%\%CODE%-*-%VER%\%CODE%-DATA.pdf" "%HOMEPATH%\Desktop\Backup\%CODE%\" /D /E /C /I /Y /H
start "" "%HOMEPATH%\Desktop\Backup\%code%"
This is assuming the later versioned directories are always created after the previous versions:
#echo off
set fp=<SET YOUR FILEPATH HERE>
set /p "code=Input Control Number: "
set cnt=0
:start
for /f "delims=" %%a in ('dir /b /s /ad /o-d "%fp%\%code%" ^| findstr "%code%" ^|more +%cnt%') do (
if exist "%%~a\%code%-DATA.pdf" (
set "found=%%~a"
goto :done
) else (
if %cnt% equ 10 goto :eof
set /a cnt+=1
goto start
)
)
:done
set cnt=
xcopy "%found%\%code%-DATA.pdf" "%USERPROFILE%\Desktop\Backup\%code%\" /D /E /C /I /Y /H
start "" "%USERPROFILE%\Desktop\Backup\%code%"
We really just check the latest folder for the file, if it does not exist, we skip that folder and try and older version until we find it, then copy the file.
Related
I have some PDF files that I need to rename and move to specific folders to be able to import into a system.
The file by default has the following name:
ex: 12345.123456/1234-12.pdf
First I need to remove the characters "," "/" "-"
#echo off
setlocal EnabledelayedExpansion
for /r "C:\importation" %%a in (*) do (
set "newname=%%~na"
set "newname=!newname:.=!"
set "newname=!newname:-=!"
set "newname=!newname:/=!"
ren "%%~a" "!newname!%%~xa"
)
Now I need to create folders with the filename (without the characters removed, ex: 12345123456123412) and rename them to the following pattern:
ex: P12345123456123412_V1_A0V0_T07-54-369-664_S00001_Volume.pdf
For that I drag the files to the following script:
#If Not "%~1" == "" For %%G In (%*) Do #MD "%%~dpG%%~nG" 2>NUL && Move /Y "%%~G" "%%~dpG%%~nG\P%%~nG_V1_A0V0_T07-54-369-664_S00001_Volume%%~xG"
I would like to do only one process, that is, join the two scripts and run only once.
Can someone help me?
Rather than dragging the files to the batch file I would like to run it and have it read the files (.pdf) from the folder
Is something like this what you are looking for?
The following will accept drag and drop of one or more files or directories, (subject to command line length restrictions). Each individually dropped PDF file and each PDF file within any dropped directory should be processed as requested.
#Echo Off
SetLocal EnableExtensions DisableDelayedExpansion
If "%~1" == "" GoTo :EOF
For %%G In (%*) Do (For %%H In ("%%~G") Do If "%%~aH" Lss "-" (
Echo Error! %%G no longer exists.
%SystemRoot%\System32\timeout.exe /T 2 /NoBreak 1>NUL
) Else If "%%~aH" GEq "d" (For %%I In ("%%~G\*.pdf") Do Call :Sub "%%~I"
) Else If /I "%%~xG" == ".pdf" (Call :Sub "%%~G"
) Else (Echo Error! %%G is not a PDF
%SystemRoot%\System32\timeout.exe /T 2 /NoBreak 1>NUL))
GoTo :EOF
:Sub
Set "basename=%~n1"
Set "basename=%basename:.=%"
MD "%~dp1%~n1" 2>NUL
If Not ErrorLevel 1 Move /Y %1 "%~dp1%~n1\P%basename:-=%_V1_A0V0_T07-54-369-664_S00001_Volume%~x1"
Exit /B
Please note, as the character / is invalid in file or directory names, I have ignored that part of your question.
I have some pdf's in a folder that I need to organize them like this:
PDF name: 123.12.123.pdf ; 102030_01.pdf; 102030_02.pdf; 123.4512.34561.23412.pdf
Now I need to create folders with the filename (without the characters removed, ex: 12345123456123412) and rename them to the following pattern: ex: P12345123456123412_V1_A0V0_T07-54-369-664_S00001.pdf
for this I have used the following code which works very well:
#Echo Off
SetLocal EnableExtensions DisableDelayedExpansion
If "%~1" == "" GoTo :EOF
For %%G In (%*) Do (For %%H In ("%%~G") Do If "%%~aH" Lss "-" (
Echo Error! %%G no longer exists.
%SystemRoot%\System32\timeout.exe /T 2 /NoBreak 1>NUL
) Else If "%%~aH" GEq "d" (For %%I In ("%%~G\*.pdf") Do Call :Sub "%%~I"
) Else If /I "%%~xG" == ".pdf" (Call :Sub "%%~G"
) Else (Echo Error! %%G is not a PDF
%SystemRoot%\System32\timeout.exe /T 2 /NoBreak 1>NUL))
GoTo :EOF
:Sub
Set "basename=%~n1"
Set "basename=%basename:.=%"
MD "%~dp1%~n1" 2>NUL
If Not ErrorLevel 1 Move /Y %1 "%~dp1%~n1\P%basename:-=%_V1_A0V0_T07-54-369-664_S00001_Volume%~x1"
Exit /B
I drag the pdfs into the .bat and it does the adjustment.
It happens that there is a case that I am not able to handle. Some pdfs need to be in the same folder, for example in the following case:
PDF name: 102030_01.pdf; 102030_02.pdf;
Note that the pdfs have the same number, only after the _ that we have the difference. In this case you would need to create a folder with the name:102030
And move the two files into it, modifying their name as follows:
102030_01.pdf -> P102030_V1_A0V0_T07-54-369-664_S00001.pdf
102030_02.pdf -> P102030_V1_A0V0_T07-54-369-664_S00002.pdf
Could anyone help?
:Sub
Set "basename=%~n1"
Set "basename=%basename:.=%"
if /i "%basename%" neq "%basename:_=%" goto sub2
MD "%~dp1%~n1" 2>NUL
If Not ErrorLevel 1 Move /Y %1 "%~dp1%~n1\P%basename:-=%_V1_A0V0_T07-54-369-664_S00001_Volume%~x1"
Exit /B
:sub2
for /f "tokens=1*delims=_" %%b in ("%basename%") do (
MD "%~dp1%%b" 2>NUL
ECHO Move /Y %1 "%~dp1%%b\P%basename:-=%_V1_A0V0_T07-54-369-664_S000%%c_Volume%~x1"
)
Exit /B
Always test on dummy data first.
This code echoes the proposed move. After verification, remove the echo keyword to activate.
Caution: My reading of the code is that - should be removed from the basename in the new name, and that _Volume should be appended to the name part, which is not shown in your examples.
Essentially, if the basename contains _ then goto sub2.
sub2 partitions the name in basename, assigning the first part to %%b and the second to %%c (See for /? from the prompt for documentation)
Then the directory is created
The md will object if the directory already exists, hence the 2>nul in the original code (suppresses error messages)
If md found that error in the original then this appears to be a problem, so the move is not executed. In the new version, it is expected that the directory may already exist, so the errorlevel processing has been removed.
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.
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
I need a batch script to copy files from a random subfolder of a specific directory into a destination directory.
For example, there will be a number of files in their own subdirectory, for example
.../source/a/file.txt
.../source/b/file.txt
So there a number of these files, and I would like to randomly select one of them and have it copied into the new directory
.../destination/file.txt
So the file.txt in the destination is just being overwritten with other files that have the same name but different content.
I'm new to batch scripting and I can't quite figure out how to select each file from a random subfolder. I'd also like it to repeat every 30 seconds until I terminate the script, but I think it should be easy enough to just make a second script that calls this .bat file every 30 seconds once I get it going.
Thanks!
This can do what you request. Just set your source directory, destination directory, and your file name filter.
#echo off
setlocal EnableExtensions EnableDelayedExpansion
pushd "...\source\"
:: Enumerate Files. Method 1
set "xCount=0"
for /r %%A in (file.txt) do if exist "%%~A" set /a "xCount+=1"
echo %xCount%
:: Select a Random File.
set /a "xIndex=%Random% %% %xCount%"
echo %xIndex%
:: Find an Copy that File. Method 1
set "xTally=0"
for /r %%A in (file.txt) do if exist "%%~A" (
if "!xTally!" EQU "%xIndex%" (
xcopy "%%~fA" "...\destination\file.txt" /Y
goto End
)
set /a "xTally+=1"
)
:End
popd
endlocal
pause
Type xcopy /? to see all of its options.
Here are some alternate loop methodologies for the file enumeration.
:: Enumerate Files. Method 2
set "xCount=0"
for /f %%A in ('dir *.txt /a:-d /s ^| find "File(s)"') do set "xCount=%%~A"
echo %xCount%
:: Find an Copy that File. Method 2
set "xTally=0"
for /f "delims=" %%A in ('dir *.txt /a:-d /b /s') do (
if "!xTally!" EQU "%xIndex%" (
xcopy "%%~fA" "...\destination\file.txt" /Y
goto End
)
set /a "xTally+=1"
)
Enjoy :)
#echo off
setlocal EnableDelayedExpansion
rem Enter into the directory that contain the folders
pushd \Fullpath\source
rem Create an array with all folders
set i=0
for /D %%a in (*) do (
set /A i+=1
set folder[!i!]=%%a
)
rem Randomly select one folder
set /A index=(%random%*i)/32768 + 1
rem Copy the desired file
copy "!folder[%index%]!\file.txt" "\Fullpath\destination" /Y
rem And return to original directory
popd
The features of batch script is
It copies all files from source to destination folder with similar structure(even retains empty folders).
Can retain N number of days recent files in Archive folder(source) remaining files will be moved to backup folder(destination).
Can be scheduled to N number of days to N number of years.
Can be used in any Source to destination folder backup.
Source folder can add N number of folder any time and delete folder or files, but Destination folder always adds the folder and never deletes any folder or file.
#echo off
Set "sourcefolder=E:\Interfaces"
Set "destinationfolder=E:\BackupInterface"
If Exist %sourcefolder% (
For /F %%* In ('Dir /b /aD "%sourcefolder%" 2^>nul') do (If Not Exist "%destinationfolder%\%%*" ( RD /S /Q "%destinationfolder%\%%*")
xcopy /e /v /i /y /q "%sourcefolder%\%%*" "%destinationfolder%\%%*"
forfiles /p "%sourcefolder%\%%*" /s /d -30 /c "cmd /c del /Q /S #file" )
) Else (echo.Source folder could not be found)
:end of batch
echo.&echo.finished!