Using batch scripting to re-name multiple .pdf files - batch-rename

I am trying to re-name multiple .pdf files using two numerals from the existing .pdf, and re-naming each .pdf with a set prefix.
In my example, I have 30 or so .pdfs named "DR DES LSEC01.pdf", "DR DES LSEC02.pdf" and so on.. up to "DR DES LSEC32.pdf". I want to keep the existing numerals (i.e. 01, 02, 03 etc.), and then add on a pre-fix (in my example, the pre-fix is "DS2019.000450-CD-SM-03").
I have created a looped batch file to loop through each .pdf and rename each by copying (I have also tried to use the rename function to no avail).
Currently, if I run the code, it either says:
1) Syntax is incorrect (if I use the 'ren' function); or
2) The system cannot find the file specified (if I use the copy function)
Here is the code
setlocal EnableDelayedExpansion
set A="DR DES LSEC"
set prefix=DS2019.000450-CD-SM-03
For %%a in (%A%) do (
For %%f in ( %%a*.pdf ) do (
set oldfilename=%%~nf
set oldname=!oldfilename:~-2!
set newname=!prefix!-!oldname!
echo %%f
echo !newname!
copy y/ %%f !newname!.pdf
)
)
pause

Can you try out below snippet
setlocal EnableDelayedExpansion
set A="DR DES LSEC"
set prefix=DS2019.000450-CD-SM-03
For %%a in (%A%) do (
For %%f in ( %%a*.pdf ) do (
set oldfilename=%%~nf
set oldname=!oldfilename:~-2!
set newname=!prefix!-!oldname!
echo %%~nf
echo !newname!
copy y/ %%~nf !newname!.pdf
)
)
pause

Related

Grouping files and 'splitting' by number and copying them inside folders

I have 5000+ files inside a directory.
I want to manage these files 'splitting' every 500 files so first pack is copied inside folder1, pack2 of other 500 files is copied in folder2 and so on.
Which .bat script can I use ?
#ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
SET "sourcedir=U:\sourcedir\t w o"
SET "destdir=U:\destdir"
SET /a destcount=0
SET /a maxcount=5
SET /a filecount=maxcount
FOR /f "delims=" %%a IN (
'dir /b /a-d "%sourcedir%\*" '
) DO (
SET /a filecount +=1
IF !filecount! geq %maxcount% (
SET /a filecount=0
SET /a destcount +=1
MD "%destdir%\folder!destcount!"
)
ECHO(COPY "%sourcedir%\%%a" "%destdir%\folder!destcount!\"
)
GOTO :EOF
You would need to change the settings of sourcedir and destdir to suit your circumstances.
maxcount sets the number of files to assign to a group.
The required COPY commands are merely ECHOed for testing purposes. After you've verified that the commands are correct, change ECHO(COPY to COPY to actually copy the files. Append >nul to suppress report messages (eg. 1 file copied)
Essentially, count the number of transfers and increment the destination-directoryname each time a group is complete, using delayedexpansion to access the run-time values of the counters

Batch File: Export selection from dynamic menu to variable?

OK, here goes...
I'm building a batch file with a menu that is set dynamically according to settings in multiple ini files, I used a script suggested to me in a previous question here.
Now, I need to add user input that export the selected menu option to another variable, in normal menu, that is not set dynamically it's easy enough, I've done it many times but I can't figure out how to do so in this instance.
Here's my current script:
#echo off
setlocal EnableDelayedExpansion
:LangMenu
for /L %%D in (1,1,20) do (
if exist Common\Settings\Data%%D.ini for /F "eol=# tokens=1,2 delims==" %%a in (Common\Settings\Data%%D.ini) do (
set line=%%a
if "!line:~2,5!" neq "clude" (
REM Define "normal" variables, i.e. Compressor, Method, etc.
set %%a=%%b
) else if "!line:~7!" neq "" (
REM Define the base array elements, i.e. D1IncludeAR=%%b, D1ExcludeAR=%%b, ...
set D%%D%%a=%%b
REM Set Show?? array elements with value equal 1, i.e. ShowAR=1, ...
REM when anyone of DiInclude?? or DiExclude?? corresponding elements was given
if defined D%%D%%a set Show!line:~7!=1
)
)
)
:LangContinue
REM Define a list of language abbreviations, i.e. "langs=AR CZ DE ..."
REM and the corresponding language names array, i.e. lang[AR]=Arabic, ...
REM At same time, calculate original OptNum
for %%a in ("AR=Arabic" "CZ=Czech" "DE=German" "EN=English" "ES=Spanish" "ESMX=Spanish (Mexico)"
"FR=French" "HU=Hungarian" "IT=Italian" "JP=Japanese" "KR=Korean" "PL=Polish"
"PR=Portuguese" "PRBR=Portuguese (Brazil)" "RU=Russian" "ZH=Chinese") do (
for /F "tokens=1,2 delims==" %%b in (%%a) do (
set "langs=!langs! %%b"
set "lang[%%b]=%%c"
set /A "OptNum+=Show%%b"
)
)
:LangSelect
cls
REM Show the language menu
set #=0
for %%a in (%langs%) do (
if defined Show%%a (
set /a #+=1
echo [!#!] !lang[%%a]!
)
)
set /p SelectLang=Please Choose The Language You Want:
if not "%SelectLang%"=="" Goto LangSet
if "%SelectLang%"=="" goto LangError
:LangError
cls
Echo ERROR: No Language Selected!!
pause
goto LangSelect
:LangSet
if "%SelectLang%"=="1" set LangIs=1
echo Selected Language = %LangIs%
Please note: I just put 1 in the set LangIs for the time being so I won't get echo is off message, it's not at all what I need, just a placeholder.
What I need is to set LangIs variable to the picked option...
An example:
Menu output is this:
[1] Arabic
[2] German
[3] English
[4] Spanish
[5] Italian
Please choose the language you want:
The variable language in the above example can be any languages, even up to 16 languages can be listed, the numbers are set dynamically so if available languages where different 5 languages it was still 1-5.
I need a way that the numbered choice entered by the user will write a variable with the Language name shown by it, so, for example, if the user type 5, I need a variable, that will have either "Arabic" or "AR" in it.
so, for example, if I use the echo command to show the choice it should output something like this if the number 1 is selected (in above menu example):
Selected Language = AR
or
Selected Language = Arabic
Or whatever language is assigned to the number 1 in the menu.
This variable, will have to be checked later on in my script up to 20 different times to check what language is selected in order to set another variable according to the selected language.
Any suggestions will be much appreciated.
:LangSelect
cls
REM Show the language menu
set #=0
for %%a in (%langs%) do (
if defined Show%%a (
set /A #+=1
echo [!#!] !lang[%%a]!
set "option[!#!]=%%a"
)
)
set /P "SelectLang=Please Choose The Language You Want: "
if defined option[%SelectLang%] Goto LangSet
:LangError
cls
Echo ERROR: Invalid Language Selected!!
pause
goto LangSelect
:LangSet
set "LangIs=!option[%SelectLang%]!"
echo Selected Language = %LangIs% (!lang[%LangIs%]!)

Saving Number of Lines in File as a Variable in Batch File

I have this really nice line in my batch file that tells me how many lines are in a file:
find /v /c "" C:\Users\c1921\mypath\myfolder\!$Unit!.txt
This is nice and gives me 31 for the particular file I'm working with. My problem is the file looks something like this:
Microsoft (R) Windows Script Host Version 5.8
Copyright (C) Microsoft Corporation. All rights reserved.
my_handled
219278
check
219276
control
219274
I want to be able to skip the first three lines entirely and then save the first value and then use the second value in my next command etc.
How do I save the number (e.g. 31) into a variable in my batch file?
On a hunch I tried setting a variable like so but it wasn't effective:
set "$testVar="""
echo !$testVar!
This command allows you to "save the number (e.g. 31) into a variable in my batch file":
for /F %%a in ('find /v /c "" ^< C:\Users\c1921\mypath\myfolder\!$Unit!.txt') do set numLines=%%a
This command allows you "to skip the first three lines entirely" and process the rest:
for /F "skip=3 delims=" %%a in (C:\Users\c1921\mypath\myfolder\!$Unit!.txt) do echo Processing: "%%a"
However, in my opinion this problem could be entirely avoided if the three first lines in the text file are supressed from the very beginning. I think this file is generated via a VBScript of JScript program that is executed this way:
cscript progname.vbs > C:\Users\c1921\mypath\myfolder\!$Unit!.txt
The first three lines in the text file may be avoided adding //nologo switch this way:
cscript //nologo progname.vbs > C:\Users\c1921\mypath\myfolder\!$Unit!.txt
#ECHO OFF
SETLOCAL
SET /a count=3
SET "first="
FOR /f "skip=3delims=" %%a IN (q25089468.txt) DO (
IF DEFINED first (CALL :show %%a) ELSE (SET "first=%%a")
)
ECHO count=%count%
GOTO :EOF
:show
ECHO first=%first% second=%1
SET /a count+=2
SET "first="
GOTO :eof
I used a file named q25089468.txt containing your data for my testing.
You appear to be asking two entirely different things - how to count the lines and how to skip the first 3, then deliver each succeeding pair to another process.

Copying files based on date modified in batch file

I am trying to copy files from one directory to another using a DOS batch script. The files I want to copy are the 4 or 3 latest files. That number will be static, but yet to be determined. Is there anyway to copy based on date modified?
Thank you
You could:
1) have the dir command sort files in the descending order of date modified;
2) use the output of the dir command in a `for loop to copy the corresponding files;
3) count to 3 (or 4) in the for loop to limit the number of files copied.
#ECHO OFF
SET "srcdir=D:\Source"
SET "tgtdir=D:\Target"
SET /A topcnt=3
SET /A cnt=0
FOR /F "tokens=*" %%F IN ('DIR /A-D /OD /TW /B "%srcdir%"') DO (
SET /A cnt+=1
SETLOCAL EnableDelayedExpansion
IF !cnt! GTR !topcnt! (ENDLOCAL & GOTO :EOF)
ENDLOCAL
COPY "%srcdir%\%%F" "%tgtdir%"
)

Variables in loops Dont Work, Batch

This is the new Script and it Still Doesn't Work
I Get The syntax of the command is incorrect.
on FOR /F "USEBACKQ tokens=*" %%A IN (TYPE "C:\Windows\System32\tasks\at!num! ^| FIND "Command") DO (
SETLOCAL ENABLEDELAYEDEXPANSION
set num=1
:START
IF NOT EXIST "C:\Windows\System32\tasks\at%num%" (GOTO:EOF)
FOR /F "USEBACKQ tokens=*" %%A IN (`TYPE "C:\Windows\System32\tasks\at!num! ^| FIND "Command"`) DO (
set var=%%A
ECHO %var%
SET /a num=%num%+1
PAUSE
)
GOTO:START
To understand your code, I'm going to break it down into logic first then try to solve it. Let me know if I miss a detail...
Set num var to 0
Begin :Loop
set num var to its current value ::NOT NEEDED - You've specified this prior to the GOTO
increment num var by +1
if myfolder\at* file exists then read at%num% and find a string then output that line to %tmp%\1.txt ::Need quotations on file location.
set F var to the line stored in %tmp%\1.txt
set F="%%F: =%%" ::Please explain what you are trying to do with this command.
set F to start on 10th character and remove the last 11 characters from the line.
echo the variable
If it doesn't exist, exit, but if it does return to :Loop
You should tell us what you are attempting. If it is as simple as saving a variable from a text file output, set F=<file.txt will work. If it didn't, then something happened prior to that command. Still... what is set F="%%F: =%%"?
Unless you are using a FOR loop variable, there is no need to use %% on each end of the variable.
If this were a FOR loop, it would look like this:
SETLOCAL ENABLEDELAYEDEXPANSION
set num=1
:START
IF NOT EXIST "myFolder\at%num%.txt" (GOTO:EOF)
FOR /F "USEBACKQ tokens=*" %%A IN (`TYPE "myFolder\at%num%.txt" ^| FIND /i "string"`) DO (
PAUSE
SET var=%%A
ECHO !var!
PAUSE
SET var=!var: =!
ECHO !var!
PAUSE
SET var=!var:~10,-11!
ECHO !var!
PAUSE
SET /a num=!num!+1
ECHO !num!
PAUSE
)
GOTO:START
One good practice to check if commands are working, such as SET, insert an ECHO on the variable and a PAUSE right after each time you believe the variable should be changed. This will track what has changed on the variable so you can see if your command was correct and the changes were made.
I'd suggest using Batch's inbuilt function for loops, see here.
Conditionally perform a command for a range of numbers
Syntax
FOR /L %%parameter IN (start,step,end) DO command
Or maybe iterating over files in a folder would be better for what you are trying to do?
Loop through files (Recurse subfolders)
Syntax
FOR /R [[drive:]path] %%parameter IN (set) DO command
Or iterating over file contents?
Loop command: against a set of files - conditionally perform
a command against each item.
Syntax
FOR /F ["options"] %%parameter IN (filenameset) DO command
FOR /F ["options"] %%parameter IN ("Text string to process") DO command
This site has plenty of examples here which should point you in the right direction.
There are a few issues with your code, I've amended as follows to get the variable populated with the contents of the temp file.
set num=0
:Loop
set /a num=%num%+1
if exist "myFolder\at*" (
TYPE "myFolder\at%num%" | FINDSTR "\<Command\>" > "%temp%\1.txt"
set /P F=<"%TEMP%\1.txt"
Echo %F%
Pause
)
I don't know if this is the problem, but have you tried enabling:
setlocal enabledelayedexpansion
Then, inside the loop (or the IF(...)), you use !foo! to signify environment variables instead of %foo%.
See setlocal /? and set /? for more information.