Kris.Mitchell
Kris.Mitchell

Reputation: 998

Batch file for loop string replacement

I have a batch file that take a directory path as a parameter.

In that file folder, there are any number of .ai.pdf or .pdf files that I need to convert to jpg's. The conversion is not my issue (I am using imageMagick) , but lopping off the full extension is.

I need to be able to either take off the full .ai.pdf (7 characters) or .pdf (4 characters) from the file name and replace it with .jpg I cannot use just ~n in the for loop because it will not take off the .ai in an instance with there is an .ai.pdf (results in file name.ai where I need just the file name)

There are quite a few posts on StackOverFlow about this StackOverFlow Example

but no matter what I attempt to try, I get an error when truncating the appropriate amount of extension off of the file name.

Here is my code. This is the first major batch file I have ever created, so I am open to anything, other than installing more programs to do the work.

The thing that kills me, is I had this working and in the shuffle from one server to another and a week of vacation, the working code got....misplaced.

@echo off
SETLOCAL ENABLEDELAYEDEXPANSION
set dir1=%1
echo recieved !dir1!
for /R %dir1% %%a in (*.pdf) DO ( 
  echo file found !a!
  set b=th_%%~nxa
  if x%b:ai.pdf=%==x%b% set b=%%~dpa!b:~0,-7!
  if not x%b:ai.pdf=%==x%b% set b=%%~dpa!b:~0,-4!

  REM convert -density 64 "%%a" +matte -resize 15%% "!b!.jpg"
  @echo !b! converted
)

ENDLOCAL

the file tells me that %~dpa!b:~0,-7! is an invalid substitution

Any ideas? Thanks for the help!

Upvotes: 1

Views: 10559

Answers (2)

James K
James K

Reputation: 4055

A few things first:

!a! and %%a are two different variables.

if x%b:ai.pdf=%==x%b% does not mean what you think it does. That will only be true when %b% does NOT contain .ai.pdf.

Again, if not x%b:ai.pdf=%==x%b% does not mean what you think. This is true when %b% DOES contain .ai.pdf.

There is no need to do any verification and cutting, just search and replace. ( That is what the %y:x=z% notation does, in this example it replaces every x within %y% with a z.) Let search and replace do the verification. It will only replace what matches the search. That will speed up the your batch file.

Lastly, since you are inside a () code block you will need to use the delayed Expansion turned on with your setlocal statement. This is because everything inside a code block is treated as if it were on a single line. That means that if you change a variable inside a code block, you will not be able to see the new value using the % notation. Instead you need to replace the %'s with !'s. For instance...

setlocal enableDelayedExpansion
set x=Hello
(
  set x=Goodbye
  echo I don't know why you say "!x!", I say "%x%".
)

...will give you the old Beatles lyric...

I don't know why you say "Goodbye", I say "Hello".

Anyway, on to your answer:

@echo off
SETLOCAL ENABLEDELAYEDEXPANSION
set dir1=%1
echo recieved !dir1!
for /R %dir1% %%a in (*.pdf) DO ( 
  :: Adding a colon to the end of the filename allows the extension to be ID'd
   : without explicitly looking at it with an IF statement, while simultaneously
  :: avoiding similar looking character groupings inside the filename.
  set b=th_%%~nxa:
  :: No need to check for case, the substitution will do that for you.
  set b=!b:.ai.pdf:=.jpg!
  set b=!b:.pdf:=.jpg!

  REM convert -density 64 "%%a" +matte -resize 15%% "!b!"
  echo %%a converted into !b!
)

ENDLOCAL

The drawback is that both the files...

X.ai.pdf
X.pdf

...will be translated into th_X.jpg, creating the possibility of duplicate filenames for two different files.

But that's intrinsic to your concept of treating both types of filenames the same. If you don't have a method for avoiding this sort of duplication it might not be a bad idea to leave the .ai on the file, thereby creating two files: th_X.jpg and th_X.ai.jpg, eliminating the possibility of duplicate filenames.

Upvotes: 6

wmz
wmz

Reputation: 3685

Hm... would this work for you:
for /R %F in (*.pdf) do @for %G in ("%~nF") do @echo %~nxF ==^> %~nG.jpg
(as executed directly from cmd, if run from batch, replace % with %%).
This has a peculiar effect of changing the case of a file to case of a directory if there exists one with the same name as base name of your file (file.pdf will become FILE.jpg if you happen to have a subdirectory called FILE), but that's it (I think).

This also assumes your base names differ (so no file.ai.pdf and file.pdf in same directory)

Upvotes: 0

Related Questions