0

I am trying to use string substitution to truncate a list of full file paths down to relative paths in an existing text file. In addition there is some basic automated renaming. The renaming works as intended but the string substitution I cannot get to work. All the documentation I could find describing string substitution used standalone strings, not strings stored in variables. So I do not know and cannot figure out the proper syntax. I have also read similar questions asked here and attempted those solutions to no avail.

Everything in my script works as intended except for this line: SET %%I=%%%I:%Temp_Dir%=%

It does not change %%I at all. The input to the FOR loop %List% is a text file that looks like this:

C:\Users\UserName\AppData\Local\Temp\Batch_Renaming_Temp\Working\out\bin\codesegment.o
C:\Users\UserName\AppData\Local\Temp\Batch_Renaming_Temp\Working\out\bin\graphic.o
C:\Users\UserName\AppData\Local\Temp\Batch_Renaming_Temp\Working\out\bin\helper.o
C:\Users\UserName\AppData\Local\Temp\Batch_Renaming_Temp\Working\out\bin\main.o
C:\Users\UserName\AppData\Local\Temp\Batch_Renaming_Temp\Working\out\bin\game.out
C:\Users\UserName\AppData\Local\Temp\Batch_Renaming_Temp\Working\out\bin
C:\Users\UserName\AppData\Local\Temp\Batch_Renaming_Temp\Working\out

The final output I get right now is identical to the above list. The desired output should look like this:

\out\bin\codesegment.o
\out\bin\graphic.o
\out\bin\helper.o
\out\bin\main.o
\out\bin\game.out
\out\bin
\out

I know the syntax is supposed to be:

SET string = C:\Users\UserName\AppData\Local\Temp\Batch_Renaming_Temp\Working\out\bin\codesegment.o
SET string = %string:C:\Users\UserName\AppData\Local\Temp\Batch_Renaming_Temp\Working =% 

As I said though, I cannot get it to work using variables in a FOR loop. I am also attempting this method of string substitution because the path of %Temp_Dir% is always at the start of every line and is always found in each line once.

Here is the whole script for reference. I would prefer a one line solution like the one I was attempting. I am aware longer solutions are available but due to reasons beyond my control the one-line string substitution is required.

@ECHO OFF
SETLOCAL EnableDelayedExpansion
SET Proj_Dir="C:\Users\UserName\Desktop\Project"
SET Temp_Dir=%temp%\Batch_Renaming_Temp\Working
SET Counter=1
SET List="%temp%\Batch_Renaming_Temp\LFN_LIST.TMP"
SET List_Final="%temp%\Batch_Renaming_Temp\LFN_LIST.TXT"

ROBOCOPY /E /MIR %Proj_Dir% "%Temp_Dir%" > NUL
CD "%Temp_Dir%"
DIR /A-D /O:N /B /S > %List%
DIR /AD /O:N /B /S | SORT /R >> %List%
TYPE NUL > %List_Final%

FOR /F "usebackq tokens=* delims=" %%I IN (%List%) DO (
    REN "%%I" !Counter!
    SET /A !Counter+=1
    SET %%I=%%%I:%Temp_Dir%=%
    ECHO %%I >> %List_Final%
)
  • 2
    You cannot do string substitution with a `FOR` variable. – Squashman Feb 19 '20 at 22:36
  • @Squashman Can I set a temporary variable equal to the FOR variable and use that in its place? – Magstriker Feb 20 '20 at 00:13
  • 1. Like @Squashman pointed out, you cannot "set" a FOR variable. – ScriptKidd Feb 20 '20 at 00:32
  • 2. You need to use either `SETLOCAL ENABLEDELAYEDEXPANSION` OR `call` if your variable's content depends on other variables, but it's not at all necessary in this case. – ScriptKidd Feb 20 '20 at 00:32
  • @HackingAddict0302 So I should do something like: ```SET string = %%I``` ```CALL SET string = %string:%Temp_Dir%=%``` Or I suppose not CALL since I already have delayed expansion enabled. – Magstriker Feb 20 '20 at 00:36
  • @Magstriker Yes, you can. But why not just use a backslash as a delimiter? – ScriptKidd Feb 20 '20 at 00:42
  • @HackingAddict0302 Because the project directory can change. Oh wait. I forgot I implemented a temporary directory. *facepalm* Thanks for saving my sanity. – Magstriker Feb 20 '20 at 01:04

1 Answers1

2
  1. Like @Squashman pointed out in the comments, you cannot "set" a FOR variable.
  2. If your variable depends on other variables indirectly, you need to use CALL SET or delayed expansion.

The easiest solution so far:

(for /F "usebackq tokens=8* delims=\" %%x in (%List%) do echo \%%y) > %List_Final%

It uses \ as a delimiter and pass the 8+th arguments to %%y, and redirects all output to %List_Final%
Tested on a Windows 10 laptop, works perfectly.

ScriptKidd
  • 803
  • 1
  • 5
  • 19