Batch script to rename PDF files using the content - batch-file

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?

Related

get two recent files from a folder in a batch script

I am trying to write a batch script that gets two recent files based on creation time from a given directory. In this batch script i want to invoke an .exe file that takes these two files as arguments.
Can someone please help me with this.
dir /a:-d-s /b /o:-d /t:c
This is the command i used that would list the names of the files in descending order based on the creation time. The command prints the result to the console but i want to assign it to some variable or array and access the top two filenames.
The following example is intended to set the two topmost returned files as 'array type' variables %Newest[1]% and %Newest[2]%
#For /F "Delims==" %%A In ('Set Newest[ 2^>NUL')Do #Set "%%A="
#For /F "Tokens=1*Delims=:" %%A In ('Dir /B/A-D-S/O-D/TC 2^>NUL^|FindStr /N "^"'
)Do #If %%A LEq 2 (Set "Newest[%%A]=%%B")Else GoTo Next
:Next
#Set Newest[ 2>NUL&&Pause
The last line was included just to show you any variables created from the loop. You would obviously replace this line with your own code, or leave it as is, and place your code beneath it. If you want to use the most recently modified date and time stamps instead of created, replace /TC with /TW on line 2
Off-topic:
Here's an example of it in use, based upon your later posted question, since deleted:
#Echo Off
For /F "Delims==" %%A In ('Set Newest 2^>NUL')Do Set "%%A="
For /F "Tokens=1-2*Delims=:" %%A In ('Dir /B/A-D-S/O-D/TC "Checkpoints" 2^>NUL^
^|FindStr /N "^"')Do If %%A LEq 2 (Set "Newest%%A=%%B")Else GoTo Next
:Next
Set "DT1="&For /F "Tokens=1*Delims=_" %%A In ('Set Newest 2^>NUL'
)Do If Not Defined DT1 (Set "DT1=%%~nB")Else Set "DT2=%%~nB"
If Not Defined DT1 Exit /B
Set "Target=Differences\Difference_%DT1%_%DT2%.csv"
Set Newest 2>NUL
Set Target 2>NUL
If Not Exist "Differences\" MD "Differences"
Pause
Here is a commented batch file for this task.
#echo off
rem Set up a local environment for this batch file with enabled command
rem extensions as required for command FOR and with disabled delayed
rem environment variable expansion to process also correct file names
rem with one or more exclamation marks in name.
setlocal EnableExtensions DisableDelayedExpansion
rem Make directory of the batch file the current directory.
rem It is possible to use any other directory on replacing
rem %~dp0 by a directory path.
pushd "%~dp0"
rem Make sure the environment variable File1 is not defined.
set "File1="
rem Get a list of files without system attribute in current directory
rem ordered by creation date with newest first and oldest last and process
rem this list of file names line by line with ignoring the batch file. The
rem loop processing the file names is exited after having assigned second
rem newest created file in this directory to the environment variable File2
rem in addition to newest file assigned to environment variable File1 with
rem a jump to the command line below the line with label RunProgram.
for /F "eol=| delims=" %%I in ('dir /A-D-S /B /O-D /TC 2^>nul') do (
if not "%%I" == "%~nx0" (
if not defined File1 (
set "File1=%%I"
) else (
set "File2=%%I"
goto RunProgram
)
)
)
rem There is no file or just one file found in current directory other
rem than this batch file and so the program cannot be executed at all.
goto EndBatch
rem Run the program with the file names of the two newest
rem created files in current directory (batch file directory).
:RunProgram
"C:\Path To Application\Application.exe" "%File1%" "%File2%"
rem Restore the initial current directory and also the initial environment
rem variables list on starting of this batch file as well as initial state
rem of command extensions and delayed environment variable expansion.
:EndBatch
popd
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.
call /? ... explains %~dp0 (drive and path of batch file) and %~nx0 (name and extension of batch file).
dir /?
echo /?
endlocal /?
for /?
goto /?
if /?
popd /?
pushd /?
rem /?
set /?
setlocal /?
Read 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 with %ComSpec% /c and the specified command line appended.

How to extract a specific line from multiple text file into a single txt file on Windows?

I have 300 files (.txt) with different name.
I want 2nd line of each file copied next to its file name into single text file.
Path of the file is D:\WCR\
Please help me with a script to be created in notepad with .Bat extension or commands to be given in cmd
Early response will be appreciated..!!
This batch file can be used for this task:
#echo off
setlocal EnableExtensions DisableDelayedExpansion
set "SourceFolder=D:\WCR"
del "%SourceFolder%\SecondLines.log" 2>nul
for %%I in ("%SourceFolder%\*.txt") do call :ProcessFile "%%I"
endlocal
goto :EOF
:ProcessFile
for /F usebackq^ skip^=1^ delims^=^ eol^= %%L in (%1) do (
>>"%SourceFolder%\SecondLines.log" echo %~nx1: %%L
goto :EOF
)
goto :EOF
Please note that command FOR ignores always empty lines. So if the second line is an empty line, the next non empty line is written into the LOG file.
The log file is created in source directory. For that reason it is important that the log file has not file extension txt.
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 /?
echo /?
endlocal /?
for /?
goto /?
set /?
setlocal /?
See also:
Where does GOTO :EOF return to?
How does the Windows Command Interpreter (CMD.EXE) parse scripts?
Microsoft article about Using command redirection operators

batch script to copy most recent file in directory

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.

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"

How to copy files into folders based on first 15 characters of file and folder name?

I want to copy more than 1000 files from a source folder like
sourcefolder\prod_de_7290022.xlsx
sourcefolder\prod_de_1652899.xlsx
sourcefolder\prod_de_6272899.xlsx
sourcefolder\prod_de_6189020.xlsx
sourcefolder\prod_de_7290022.wav
sourcefolder\prod_de_1652899.wav
sourcefolder\prod_de_6272899.wav
sourcefolder\prod_de_6189020.wav
sourcefolder\prod_de_7290022_mark.xlsx
sourcefolder\prod_de_1652899_mark.xlsx
sourcefolder\prod_de_6272899_mark.xlsx
sourcefolder\prod_de_6189020_mark.xlsx
to the right destination folder. The folder names are - based on another routine - long and only the first 15 characters are identical with the first 15 characters of each file name, like:
destination\prod_de_1652899_tool_big\
destination\prod_de_6272899_bike_red\
destination\prod_de_6189020_bike-green\
destination\prod_de_7290022_camera_good\
I am looking for a routine to copy the files into the folder, like sourcefolder\prod_de_1652899.xlsx into destination\prod_de_1652899_tool_big\.
Is here anyone with a good idea for a batch/script?
I suggest to use this commented batch code for this task:
#echo off
setlocal EnableExtensions DisableDelayedExpansion
set "SourceFolder=sourcefolder"
set "TargetFolder=destination"
rem Call subroutine CopyFile for each non hidden and
rem non system file found in specified source folder
rem and then exit processing of this batch file.
for %%I in ("%SourceFolder%\*") do call :CopyFile "%%~fI"
endlocal
goto :EOF
rem This is a subroutine called for each file in source folder.
rem It takes the first 15 characters from each file name passed
rem to this subroutine via first parameter and search for a
rem folder in target folder starting with same 15 characters.
rem If such a folder is found, the file is copied to this folder
rem and the subroutine is exited.
rem Otherwise a new folder is created for the file and if
rem this is indeed successful, the file is copied into the
rem newly created folder with an appropriate message.
:CopyFile
set "FileName=%~n1"
set "DirectoryName=%FileName:~0,15%"
for /D %%D in ("%TargetFolder%\%DirectoryName%*") do (
copy /B /Y %1 /B "%%~D\" >nul
goto :EOF
)
set "NewFolder=%TargetFolder%\%DirectoryName%_new"
md "%NewFolder%"
if exist "%NewFolder%\" (
echo Created new folder: %NewFolder%
copy /B /Y %1 /B "%NewFolder%\" >nul
goto :EOF
)
echo Failed to create folder: %NewFolder%
echo Could not copy file: %1
goto :EOF
To understand the commands used and how they work, open a command prompt window, execute there the following commands, and read the displayed help pages for each command, entirely and carefully.
call /?
copy /?
echo /?
endlocal /?
for /?
goto /?
if /?
md /?
rem /?
set /?
setlocal /?

Resources