0

I have a windows directory which contains folders with names like:

Lot 1
Lot 2
Lot 5
Lot A
Block A
Block C

Each of these folders contains PDF survey drawings. The names of the files are inconsequential. My goal is to prefix each PDF in ONLY LOT FOLDERS with an edited version of the name of its parent folder. Instead of adding the prefix Lot 1_ to the filenames of files in folder Lot 1 I would like to add L1_ to the filename.

Currently, I have a batch file which will add any prefix entered into a prompt to all PDFs in current folder. This means I have to go into each folder & run the batch script. This is tedious as I have thousands to deal with.

This is what the code looks like:

Set /p prefix="Enter Prefix to add to file names: "
FOR /f "delims=" %%F IN ('DIR /a-d /b *.PDF') DO (RENAME "%%F" %prefix%_"%%F")

I have been messing around trying to create a batch file to iterate through all folders with Lot and a space in their names and so far all I can do is use a for loop to get all the Lotwhatevernumber names and output them to a text file.

This is what that code looks like:

for /f "delims=" %%F in ('dir /A:D /b Lot*') do echo %%F >> folders.txt

and then I get text file with:

Lot 1
Lot 2
Lot 5
Lot A

I can also output just the number portion of the Folder name. That code:

for /f "tokens=2" %%F in ('dir /A:D /b Lot*') do echo %%F >> folders2.txt

and then I get text file with:

1
2
5
A

I felt like I was real close with that last one, but what I tried to do was instead of echoing to folders2.txt I wanted to enter another for loop where I would rename each file in Lot %%F and add a prefix of L%%F and the rest of the filename.

Anyone has any ideas?

Someone from another forum gave me this which works but the first file in each Lot folder gets named twice...I can't figure out why.

Someone on another forum provided the following which works but the first file in each Lot folder gets labelled L_ twice and I don't know why....

@echo off & setlocal
for /f "tokens=*" %%a in ('dir /b /ad lot*') do (
for %%b in ("%%a"\*.pdf) do call :xx "%%~dpb" "%%~nxb"
)
goto :eof

:xx
set z=%~1
set z=%z:~0,-1%
for %%c in ("%z%") do set k=%%~nc
set k=%k:lot =L%
echo ren %1%2 %k%_%2
ren %1%2 %k%_%2
Phil
  • 13
  • 3
  • I the code you recently posted: try to replace `for %%b in ("%%a"\*.pdf) do` with `for /f "tokens=*" %%b in ('dir /b /a-d "%%a\*.pdf"') do`, because with a normal `for` loop (without `/F`) renamed files may be recognised again, because the list of items to process is not generated in advance but block-wise; take also a look at this thread about that: [At which point does `for` or `for /R` enumerate the directory (tree)?](https://stackoverflow.com/q/31975093) – aschipfl Nov 29 '19 at 18:20

1 Answers1

0

What about this:

@echo off
rem // Switch to the target directory:
pushd "D:\Target" && (
    rem /* Loop through all directories whose names begin with `Lot` + SPACE;
    rem    the `findstr` portion further filters the directory names so that
    rem    they must begin with `Lot` + SPACE + a character other than SPACE;
    rem    everything starting at a potential following SPACE is ignored: */
    for /F "tokens=1-2" %%C in ('
        2^> nul dir /B /A:D "Lot *" ^| findstr /I "^Lot [^ ]"
    ') do (
        rem /* Loop through all `*.pdf` files in the currently iterated directory;
        rem    the `findstr` portion further filters the file names so that they must
        rem    not equal `L` + the second token from the outer loop + something containing
        rem    a `_` + `.pdf`, because such files are considered as already renamed: */
        for /F "delims=" %%F in ('
            2^> nul dir /B /A:-D "%%~C %%~D\*.pdf" ^| findstr /I /V "^L%%~D_.*\.pdf$"
        ') do (
            rem // Check whether target file name already exists:
            if exist "%%~C %%~D\L%%~D_%%F" (
                rem // Collision, hence skip file and return error message:
                >&2 echo Collision: cannot rename "%%~C %%~D\%%F" to "L%%~D_%%F"!
            ) else (
                rem // No collision, so actually rename the currently iterated file:
                ECHO ren "%%~C %%~D\%%F" "L%%~D_%%F"
            )
        )
    )
    rem // Return to original working directory:
    popd
)

After having tested for the correct output, remove the upper-case ECHO from the ren command!

aschipfl
  • 33,626
  • 12
  • 54
  • 99
  • Meanwhile I fixed an error in the code and further improved the script; want to give it a try? – aschipfl Nov 29 '19 at 18:16
  • I like yours! Works fantastic. Thanks so much. I'll probably add a line or two to get current directory instead of copying and pasting the target directory text at the beginning but I am really excited about this. Wish I had it sooner...I've gone through a couple thousand lot folders without this. – Phil Nov 29 '19 at 21:52