0

I'm attempting to do some automation for a project I'm working on, and am running into a snag. For some background, I want my script to be able to do:

  1. When double clicked/ran, I want it to copy a file and paste it in my current directory.
  2. I want it to rename it/increment a number at the end of a filename, for every consecutive file I create. I.e., if there is already a "XXX Form 1.pdf" in the directory and I run this script, I want it to create a new file called "XXX Form 2.pdf."

As mentioned in the title, my script is able to do this if I copy and paste it line by line into Windows CMD. But if I double click/run the CMD file with this script, it only partially works. It will work the first time it's ran, i.e. when "XXX Form 1.pdf" gets copied/created. But when I run it again, it fails to create a second file ("XXX Form 2.pdf").

I have tried to "debug" this by sending outputs of certain key vaiables to a text file, but from the get go nearly all of my variables are BLANK as described by "ECHO ON" showing up in my text file. But they shouldn't be since it works when manually typed out in CMD.

Here is my code:

for %%I in (.) do set dateName=%%~nxI

cd ..

for %%I in (.) do set WOName=%%~nxI

cd ..

for %%I in (.) do set MPFName=%%~nxI

cd ..

set dirName="H:/Test Structure for Cataloging Line Clearance/CLASSIFIED/%WOName%/%dateName%/%MPFName% - %WOName% - %dateName% - Line Clearance Form 1.pdf"
if exist %dirName% (
set "first=%dirName:.pdf=" & set "last=%"

set /A num=%first:~-16,1%

set "prefix="
set "res=%dirName%"

for /f "tokens=1 delims=%num%" %%i in ("%res%") do (set prefix=%%i)
set /A num=%num%+1

set "fullPath=%prefix%%num%.pdf""

set "dirName=%fullPath%"
)

copy "H:/Test Structure for Cataloging Line Clearance/Template (DO NOT EDIT) - 2028_Line-Clearance-Verification.pdf" %dirName%

This is my first time writing CMD scripts, so it's possible I'm missing something fundamental. Any and all tips are appreciated. I have learned that, for instance, %%i does not work when manually performing commands in CMD (should be %i), but it does work in a .CMD file. Maybe something like that is why this is failing when I run the file?

EDIT: For further clarification, I added Echo %first% right after set "first=%dirName:.pdf=" & set "last=%"

This is the first line it fails (prints ECHO ON in the text file I write to). Meaning, %first% does not get populated. I have tried to echo every variable within the 'if' block, and they all are blank. The fact ECHO is running within the block must mean the 'if' condition is true, so something has to be going on with the commands within the block. 'ECHO %dirName%' prints the directory path appropriately.

Adrian Mole
  • 49,934
  • 160
  • 51
  • 83
Pork
  • 1
  • 1
  • 1
    [at least a part of your problem](https://stackoverflow.com/questions/30282784/variables-are-not-behaving-as-expected/30284028#30284028) – Stephan Sep 12 '22 at 17:09

1 Answers1

0

This should do what you describe:

@echo off
setlocal

:: current directory's name
for %%I in ("%cd%") do set dateName=%%~nxI

cd ..
:: its parent's name

for %%I in ("%cd%") do set WOName=%%~nxI

cd ..

:: its grandparent's name
for %%I in ("%cd%") do set MPFName=%%~nxI

cd ..

:: Now at specified directory's great-grandparent

:: destination directory name, file name and serial number
set "destdirName=C:\Test Structure for Cataloging Line Clearance\CLASSIFIED\%WOName%\%dateName%"
set "destfilename=%MPFName% - %WOName% - %dateName% - Line Clearance Form"
set /a serialnumber=1

:findnewserial
if exist "%destdirName%\%destfilename% %serialnumber%.pdf" set /a serialnumber+=1&goto findnewserial

md "%destdirName%" 2>nul
copy nul "%destdirName%\%destfilename% %serialnumber%.pdf"

Note that I've used drive C:

Naturally, test against some dummy data before applying to live data.

First grab the names of the current directory, its parent and grandparent. %cd% is the current directory; it needs to be quoted since it likely contains spaces. This assigns the selected parts of the name to the three variables.

Next, establish the required directory name and filename as separate variables. It's far easier to construct a string if the parts used are unquoted. The set syntax I've shown will ensure that trailing spaces on lines are not included in the value assigned.

We need to find the next serial number, so it's simply a question of trying to find a file made from the parts, and changing the serial number until the next unused filename has been found.

Then ensure the directory exists by attempting to create it; the 2>nul suppresses the directory already exists error message.

Then copy the template file. I used nul as that file. change to suit yourself, remembering to "quote the name" if it contains spaces.

Magoo
  • 77,302
  • 8
  • 62
  • 84