batch script to copy most recent file in directory - batch-file

Hi here is what I need to get accomplished and not sure how. I have a SQL sever that does daily backup of the transaction logs to a local E drive on the sql server. What I need to do is copy the most recent log file from that server to a remote server. Once I get the script to work I will then setup as a schedule task. Can anyone give me advice on how to copy the most recent file to a different server. This will run daily as well so the file name date will change that is why I need the most recent file in the directory where the backup are going.

Use in the batch file these command lines:
for /F "delims=" %%I in ('dir "C:\Path To\Source Folder\*" /A-D-H /B /O-D /TW 2^>nul') do copy /B /Y "C:\Path To\Source Folder\%%I" "X:\Path To\Destination Folder\" >nul & goto FileCopied
:FileCopied
rem More commands after copying file with newest last modification date.
This code is explained for example at Get newest file in directory with specific extension. Command DIR excludes here also files with hidden attribute set as command COPY does not copy hidden files. The destination folder must already exist.
Enhanced version with real folder paths:
#echo off
setlocal EnableExtensions DisableDelayedExpansion
set "SourceFolder=E:\MSSQL\Backup\AaaImaging"
set "TargetFolder=\\servername\F\MSSQL\Backup\Pablo"
for /F "delims=" %%I in ('dir "%SourceFolder%\*" /A-D-H /B /O-D /TW 2^>nul') do copy /B /Y "%SourceFolder%\%%I" "%TargetFolder%\" >nul & goto FileCopied
:FileCopied
rem More commands after copying file with newest last modification date.
endlocal
For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.
copy /?
dir /?
echo /?
endlocal /?
for /?
goto /?
rem /?
set /?
setlocal /?
Read also the Microsoft documentation page about Using command redirection operators and Single line with multiple commands using Windows batch file.

Related

Jenkins job is failing with for loop in command

In Jenkins, I have few Commands that I am trying to implement in the BAT File. So I have 2 BAT Files (RUN.BAT & CHANGE.BAT). In RUN.BAT, Commands are as follows:
CD\
E:
CD E:\RESULTS\1
mkdir 1
xcopy E:\I1\0 E:\RESULTS\1
Above Given Command would Go to the particular folder and Make a folder named as "1" & then the XCOPY line would copy the contents from folder "O" to folder "1".
Now lets come to CHANGE.BAT here the commands are:
for /f "tokens=1-7 delims=-:. " %%a in ("%date% %time%") do ren E:\RESULTS\1 %%a%%b%%c_%%d%%e%%f%%g
This command would change the folder name to the Date & Time of the current System.
Here is the issue, the above-given bat files runs completely fine when I call them on my CMD. But the same doesn't work on the JENKINS & throws me "The syntax of the command is incorrect".
What I am not able to understand is, .bat file works in CMD but the same doesn't work in Jenkins.
Kindly guide me.
The two batch files RUN.BAT and CHANGE.BAT can be replaced by a single batch file with just one command line:
#for /F "tokens=1-6 delims=/: " %%I in ('%SystemRoot%\System32\robocopy.exe "%SystemDrive%\|" . /NJH') do #%SystemRoot%\System32\robocopy.exe "E:\I1\0" "E:\RESULTS\%%I-%%J-%%K_%%L%%M%%N" /E /R:3 /W:2 /NDL /NFL /NJH /NJS & goto :EOF
ROBOCOPY is the replacement for XCOPY and is available by default since Windows Vista and Windows Server 2003.
There is first executed ROBOCOPY with an invalid source directory path to get output an error message by ROBOCOPY which contains current date and time in a region independent format. Region independent format means that the format of date and time does not depend on which country is configured for the used account which is for Jenkins running as service the built-in local system account. That is most likely the reason for the error message output by command REN. The new folder name is different on execution of the batch file with settings for system account in comparison to execution of the batch file with your user account.
Then ROBOCOPY is run once again with correct source directory path and the destination directory path with yyyy-MM-dd_hhmmss as directory name in E:\RESULTS.
ROBOCOPY creates automatically like XCOPY the entire directory tree to destination directory if the destination directory does not already exist.
The command goto :EOF is required to end the batch file execution after copying the files because of ROBOCOPY outputs a second line on error which would be otherwise processed also by FOR. It is possible to replace the predefined label :EOF by any other label which is written on next line if there are more lines to execute like:
#echo off
setlocal EnableExtensions DisableDelayedExpansion
for /F "tokens=1-6 delims=/: " %%I in ('%SystemRoot%\System32\robocopy.exe "%SystemDrive%\|" . /NJH') do %SystemRoot%\System32\robocopy.exe "E:\I1\0" "E:\RESULTS\%%I-%%J-%%K_%%L%%M%%N" /E /R:3 /W:2 /NDL /NFL /NJH /NJS & goto FilesCopied
:FilesCopied
rem More command lines to execute.
endlocal
For completeness a solution working also on Windows XP and all later Windows versions:
#echo off
setlocal EnableExtensions DisableDelayedExpansion
for /F "tokens=2 delims==." %%I in ('%SystemRoot%\System32\wbem\wmic.exe OS GET LocalDateTime /VALUE') do set "CurrentDateTime=%%I"
set "CurrentDateTime=%CurrentDateTime:~0,4%-%CurrentDateTime:~4,2%-%CurrentDateTime:~6,2%_%CurrentDateTime:~8,6%"
%SystemRoot%\System32\xcopy.exe "E:\I1\0" "E:\RESULTS\%CurrentDateTime%\" /I /R /Q /Y >nul
endlocal
For a full explanation what is output by ROBOCOPY on running it first with an invalid source directory path and how FOR processes this output see Time is set incorrectly after midnight. The Windows XP solution with WMIC is explained in detail in the same answer.
For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.
echo /?
endlocal /?
for /?
goto /?
if /?
robocopy /?
set /?
setlocal /?
wmic /?
wmic os /?
wmic os get /?
wmic os get localdatetime /?
xcopy /?

Batch script to rename PDF files using the content

I have a batch script used to extract PDF information and rename the PDF then.
The script is working fine for 1 PDF file but I need to use it directly in a folder with a lot of PDF files.
So how to do it?
The script needs to run for each PDF file, one by one until the end.
Once the PDF file is renamed next the file is moved in another folder, so the PDF file remaining in the folder need the same thing. And when the folder is empty the script exits.
#echo off
setlocal enabledelayedexpansion
set PDF="Renommer_Manuellement.pdf"
set text="Renommer_Manuellement.txt"
set DSUBDIX=%USERPROFILE%\Google Drive\CLASSEURS
ren *.pdf %PDF%
pdftotext -raw %PDF%
for /f "delims=- tokens=2" %%a in ('find "Number=" %text%') do set numeroa=%%a
for /f "delims== tokens=2" %%a in ('find "NAME=" %text%') do set nature=%%a
ren "%PDF%" "OCC-%numeroa:~0,5%#!nature!.pdf"
move "%PDF%" "OCC-%numeroa:~0,5%#!nature!.pdf" "XYZ FOLDER"
exit
Perhaps this commented batch file code works for moving all PDF files in current directory to subdirectory XYZ FOLDER with new file name determined from contents of each PDF file.
#echo off
setlocal EnableExtensions DisableDelayedExpansion
rem Don't know what this environment variable is for. It is not used by this code.
set "DSUBDIX=%USERPROFILE%\Google Drive\CLASSEURS"
md "XYZ FOLDER" 2>nul
for /F "delims=" %%I in ('dir *.pdf /A-D /B 2^>nul') do call :RenamePDF "%%~fI"
rem Restore initial command environment and exit batch file processing.
endlocal
goto :EOF
:RenamePDF
set "FilePDF=%~1"
set "FileTXT=%~dpn1.txt"
pdftotext.exe -raw "%FilePDF%"
for /F "delims=- tokens=2" %%J in ('%SystemRoot%\System32\find.exe "Number=" "%FileTXT%"') do set "numeroa=%%J"
for /F "delims== tokens=2" %%J in ('%SystemRoot%\System32\find.exe "NAME=" "%FileTXT%"') do set "nature=%%J"
rem The text version of the PDF file is no longer needed.
del "%FileTXT%"
rem Move the PDF file to XYZ FOLDER and rename the file while moving it.
move "%FilePDF%" "XYZ FOLDER\OCC-%numeroa:~0,5%#%nature%.pdf"
rem The file movement could fail in case of a PDF file with new
rem name exists already in target folder. In this case rename
rem the PDF file in its current folder.
if errorlevel 1 ren "%FilePDF%" "OCC-%numeroa:~0,5%#%nature%.pdf"
rem Exit the subroutine RenamePDF and continue with FOR loop in main code.
goto :EOF
It is unclear for me why each *.pdf file should be moved into a subdirectory with new file name.
This is not really necessary in my point of view. The command REN could be enough.
For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.
call /?
del /?
dir /?
echo /?
endlocal /?
find /?
for /?
goto /?
md /?
move /?
rem /?
ren /?
set /?
setlocal /?
Read also the Microsoft article about Using Command Redirection Operators for an explanation of 2>nul. The redirection operator > must be escaped with caret character ^ on FOR command line to be interpreted as literal character when Windows command interpreter processes this command line before executing command FOR which executes the embedded dir command line with using a separate command process started in background.
See also Where does GOTO :EOF return to?

Why does a batch file working before not work anymore as expected on some machines?

I have a batch script already working for some months. The purpose of the script is to create a folder based on the file name and rename the folder accordingly for a certain purpose. However, it stops moving the files to the created folder in the loop. I tested it on other machine and it was working fine, but on a particular machine; it is just not working.
What can I do to make the loop effective and why did the batch stop working (moving files to folder) after working for many months now?
setlocal EnableDelayedExpansion
for /F %%a in ('dir "C:\Program Files\WinSCP\Unconverted" /a-d /b') do (
if not "%%~dpnxa"=="%~dpnx0" call :func "%%~a"
:func
set file=%~1
set dir=%file:~0,49%
mkdir "C:\Program Files\WinSCP\Unconverted\%dir%_fdc" 2>nul
rem ECHO "%file%"
rem ECHO "C:\Program Files\WinSCP\Unconverted\%dir%_fdc"
move /Y "C:\Program Files\WinSCP\Unconverted\%file%" "C:\Program Files\WinSCP\Unconverted\%dir%_fdc"
)
start "" "C:\Program Files\WinSCP\hide_conversion_window.exe"
I rewrote and commented the batch file as it contains several issues whereby most were not problematic as long as this batch file is stored in %ProgramFiles%\WinSCP\Unconverted and this directory is also the current directory on execution of the batch file as on double clicking the batch file.
#echo off
setlocal EnableExtensions DisableDelayedExpansion
set "SourceFolder=%ProgramFiles%\WinSCP\Unconverted"
rem Process all files in source folder found by command DIR with ignoring
rem subfolders and listed in bare format which means only file names with
rem file extension but without file path. The batch file itself is skipped
rem if being also stored in the source folder specified above.
for /F "delims=" %%I in ('dir "%SourceFolder%\*" /A-D /B 2^>nul') do (
if /I not "%SourceFolder%\%%I"=="%~f0" call :MoveFile "%SourceFolder%\%%I"
)
rem Execute converter through AutoIt in a separate command process and
rem while conversion is running continue with batch processing which means
rem restoring previous environment and finally exiting batch file processing.
start "" "%ProgramFiles%\WinSCP\hide_conversion_window.exe"
endlocal
goto :EOF
rem MoveFile is a subroutine which expects to be called with one argument
rem being the name of the file to move with full file name which means
rem with file path, file name and file extension.
rem The first 49 characters of the file name define the name for target
rem folder on which "_fdc" must be appended for completion. This folder
rem is created without verification on success and then the file is
rem moved into this folder again without verification on success.
:MoveFile
set "FileName=%~nx1"
set "FolderName=%FileName:~0,49%_fdc"
mkdir "%~dp1\%FolderName%" 2>nul
move /Y "%~1" "%~dp1\%FolderName%\" >nul
goto :EOF
This batch file works for batch file being stored in a different folder than source folder or current directory is a different directory than the folder containing the batch file or a found file contains a space character or any other special character like &()[]{}^=;!'+,`~.
For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.
call /?
echo /?
endlocal /?
for /?
goto /?
if /?
mkdir /?
move /?
set /?
setlocal /?
start /?
Read also the Microsoft article about Using Command Redirection Operators.
Thanks for the suggestion oldabi. Sometimes things do work and we are thinking is all perfect until it breaks down. Thanks for the suggestion. I just realised my mistake about missing bracket.
SETLOCAL ENABLEDELAYEDEXPANSION
for /F %%a in ('dir "C:\Program Files\WinSCP\Unconverted" /a-d /b') do (
if not "%%~dpnxa"=="%~dpnx0" call :func "%%~a" )
goto conversion
:conversion
rem ::execute converter through autoit
start "" "C:\Program Files\WinSCP\hide_conversion_window.exe"
:func
set file=%~1
set dir=%file:~0,49%
mkdir "C:\Program Files\WinSCP\Unconverted\%dir%_fdc" 2>nul
rem ECHO "%file%"
rem ECHO "C:\Program Files\WinSCP\Unconverted\%dir%_fdc"
MOVE /Y "C:\Program Files\WinSCP\Unconverted\%file%" "C:\Program Files\WinSCP\Unconverted\%dir%_fdc"

Forfiles with 7z zip ONLY last modified file

I am trying to zip only last modified file from a folder to help my workflow with bat file
but its giving an error
ERROR: No files found with the specified search criteria.
Here is my complete code
#ECHO ON
SET "SourceDir=C:\Users\user1\Documents\Work"
SET "ZipName=testing.zip"
SET "DestDir=C:\Users\user1\Documents\Work\result"
SET "now=%date:~4%"
CD /D "%DestDir%"
FORFILES /D %now% /m *.csv /c "cmd /c 7z.exe a -aoa -tzip %ZipName% %SourceDir% "
I am pretty sure there is file last modified today. I assume its didn't recognise the sourcedir? Am I missing in the quote?
I suggest not using command FORFILES, but use instead the commands FOR and DIR.
#echo off
set "SourceDir=%USERPROFILE%\Documents\Work"
set "ZipName=testing.zip"
set "DestDir=%USERPROFILE%\Documents\Work\result"
for /F "delims=" %%I in ('dir "%SourceDir%\*" /A-D /B /O-D 2^>nul') do 7z.exe a -aoa -tzip "%DestDir%\%ZipName%" "%SourceDir%\%%I" & goto Done
:Done
DIR searches in specified source directory with wildcard pattern * because of /A-D (attribute not directory) only for files and outputs them because of /B (bare format) with file name only ordered by last modification date in reverse order because of /O-D which means newest file is output first.
FOR process this output by DIR line by line. For the first line 7z.exe is called to compress the file into the ZIP archive file.
Then goto :Done is executed to exit the FOR loop as all other files found and output by DIR are of no interest.
I suggest to specify 7z.exe with full path in the batch file.
2^>nul redirects the error message output by DIR if no file is found in source directory to device NUL to suppress it. The redirection operator > must be escaped here with caret character ^ to be interpreted as literal character on Windows command interpreter parses the entire FOR command line. The escape character ^ is already removed later on execution of DIR command line in a separate command process opened by FOR in background.
Another version processing only files with archive attribute set and clear the archive attribute for each file compressed into the ZIP archive file.
#echo off
set "SourceDir=%USERPROFILE%\Documents\Work"
set "ZipName=testing.zip"
set "DestDir=%USERPROFILE%\Documents\Work\result"
for /F "delims=" %%I in ('dir "%SourceDir%\*" /AA-D /B 2^>nul') do (
7z.exe a -aoa -tzip "%DestDir%\%ZipName%" "%SourceDir%\%%I"
%SystemRoot%\System32\attrib.exe -a "%SourceDir%\%%I"
)
For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.
attrib /?
dir /?
echo /?
for /?
goto /?
set /?
Read also the Microsoft article about Using Command Redirection Operators.

How to copy one file to a specific subdirectory in all application data directories in C:\Users?

One Windows 7 x64 I am trying to copy one file to
C:\users\profilename\AppData\Roaming\Autodesk\AutoCAD 2011\R18.1\enu\Plotters
I would like the batch to copy this file to all user profiles that exist on the client PC silently with no prompts.
The code I have tried so far with no luck:
#echo off
xcopy /I /Y "%~dp0myfile.pc3" "C:\Users\*\Appdata\Roaming\Autodesk\AutoCAD 2011\R18.1\enu\Plotters"
Any ideas on how to do this with a batch file?
Wildcards can't be used inside a folder path. The Windows command interpreter does support that.
You could use the following code:
#echo off
setlocal EnableExtensions
set "TargetPath=AppData\Roaming\Autodesk\AutoCAD 2011\R18.1\enu\Plotters"
rem Get path of folder containing the users' profile folders.
for /F %%I in ("%PUBLIC%") do set "UsersFolder=%%~dpI"
rem Copy file into a subdirectory of each non standard user profile folder.
for /D %%I in (%UsersFolder%*) do (
if /I not "%%I" == "%PUBLIC%" (
if /I not "%%~nxI" == "Default" (
if not exist "%%I\%TargetPath%\*" md "%%I\%TargetPath%"
copy /B /Y "%~dp0myfile.pc3" "%%I\%TargetPath%\" >nul
)
)
)
endlocal
The subfolders Default and Public are skipped by this batch code.
This batch file must be of course run as administrator as otherwise the file can be only copied to %APPDATA%\Autodesk\AutoCAD 2011\R18.1\enu\Plotters, i.e. the appropriate subdirectory in the application data directory of AutoCAD 2011 of the current user account.
For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.
copy /?
echo /?
endlocal /?
for /?
if /?
md /?
rem /?
set /?
setlocal /?

Resources