Articles

Solved Replace text string with contents of variable

February 2, 2013 at 19:52:45
Specs: Windows 7 SP1, 3.4 GHz / 16 GB

I know how to replace text in a string like %var:yes=no% but the script I'm working on is a bit more complicated than that.

I'm looping though a bunch of files and need to replace part of their file name. I have the file name saved as !fp! and the title I'm trying to add to it is !title! and the title is different for each file

example file name: something_-_01___[1080].mkv
example title: episode_one
end result: something_-_01_episode_one__[1080].mkv

!fp:___=_!title!__!

That is simply returning the file name minus the three underscores. Is it possible to use a variable as the replace text? I haven't been able to find any examples where the replace text isn't a static variable.


See More: Replace text string with contents of variable

Report •


#1
February 2, 2013 at 20:43:56

You probably need to use a combination of percents and exlms, like:
setlocal enabledelayedexpansion
set a=aaaaaaa_bbbbb_cccc
set d=DDD
set repl=_bbbbb_
set new=!a:%repl%=_%d%_!

Report •

#2
February 2, 2013 at 21:02:07

That doesn't work as I'm trying to do the replace inside of a for loop, so the variable value isn't static.

I'll post my code but it relies on having the other files to interact with.

@echo off
setlocal EnableDelayedExpansion

set /a line=1
for /f %%a in (ep_titles.txt) do (
set e!line!=%%a
set /a line=!line!+1
)

for /f "delims=" %%I in ('dir /b *.test') do (
set fp=%%I
set num=!fp:*-_=!
set num=!num:_-___pball_[1080p_bd-rip][].test=!

call :zero

set VAR2=e!num!
for /f %%A in ("!VAR2!") do set title=!%%A!

echo !fp:___=_!title!__!
echo.

)
pause
goto :eof

:zero
set sigh=!num:~0,1!
if !sigh! == 0 (
set num=!num:~1!
goto :zero
)
exit /b

Requirements:
ep_titles.txt - one episode title per line (you can make them up)
baccano!_-_01_-___pball_[1080p_bd-rip][].test (files to have episode title added to)
baccano!_-_02_-___pball_[1080p_bd-rip][].test
baccano!_-_03_-___pball_[1080p_bd-rip][].test

The first loop reads the episode titles from the text file and sets them to numbered variables. Next it loops through the files to be renamed and it gets the episode number to get the corresponding episode title. Lastly it tries to add the episode title to the file name.

I realize this could be done in a lot less lines and much much easier in just about any other language. But I seem to be a masochist for using batch scripts. Though I'll probably just end up doing this in python as it'll be a few lines of code at most.


Report •

#3
February 2, 2013 at 23:49:58
✔ Best Answer

ok, here's what I did (VERY rough draft):
@echo off
setlocal EnableDelayedExpansion

set /a line=1
for /f "tokens=*" %%a in (ep.txt) do (
set e!line!=%%a
set /a line+=1
)

for /f "delims=" %%I in ('dir /b *.test') do (
set fp=%%I
:: i didn't understand this part... a WIN-7 thing?
set num=!fp:*-_=!
set num=!num:_-___pball_[1080p_bd-rip][].test=!

call :zero
echo NUM: !num!

set VAR2=e!num!
call :rep
)
goto :eof

:rep
echo var2: !%var2%!
set zzz=!%var2%!
echo OUT1: !fp:___=_%var2%__!
set out=!fp:___=_%zzz%__!
echo OUT2: %out%
echo.

pause
goto :eof

:zero
set sigh=!num:~0,1!
if !sigh! == 0 (
set num=!num:~1!
goto :zero
)
exit /b
::====== end


Report •

Related Solutions

#4
February 3, 2013 at 09:11:20

Awesome this works quite nicely. I can't recall using subroutines before this script so I never knew you could do things in the subroutine that don't work directly in for loops.

The two lines under you comment about not understanding. The first line replaces everything before the numbers in the file name and the second line removes everything after the numbers. It's not exactly how I wanted to do it, but I can update that part now, using the same type of work around you came up with for the final replace.

Below is my final code (for now).

@echo off
setlocal EnableDelayedExpansion

REM reads the episode titles into numbered variables, line 1 is episode 1 (!e1!), line 2 episode 2 (!e2!), etc, etc
set /a line=0
for /f %%a in (ep_titles.txt) do (
set /a line=!line!+1
set e!line!=%%a
)

setlocal DisableDelayedExpansion

REM loops through the files to have titles added to
for /f "delims=" %%I in ('dir /b *.test') do (
set fp=%%I

setlocal EnableDelayedExpansion

REM returns the episode number as !num!
call :number

REM removes zero padding from !num! as variables from before aren't zero padded
call :zero

REM builds the episode title variable name
set VAR2=e!numz!

REM evaulates for the episode title
for /f %%A in ("!VAR2!") do set title=!%%A!

REM renames the filename if title isn't in it already
if not !end! == "" (
echo !beg!!num!_-_!title!!end:~3!
rename "%~dp0!fp!" "!beg!!num!_-_!title!!end:~3!"
echo.
)

ENDLOCAL
)
pause
goto :eof

:number
set end=_-__!fp:*_-__=!
REM if title is in file name already it clears !end! (basically the replace above does nothing)
if !end:~4! == !fp! set end=""
set beg=!fp:%end%=!
set num=!beg:*-_=!
set beg=!beg:%num%=!
exit /b

:zero
set numz=!num!
:repeat
set sigh=!numz:~0,1!
if !sigh! == 0 (
set numz=!numz:~1!
goto :repeat
)
exit /b

Well that's my updated script which appears to work find other than when certain characters are in the episode titles like ^!. I'm sure it's possible to escape those characters but I can't be bother to put more effort in this now. Considering I did make it in python and it's only around 10 lines and more robust.


Report •

#5
February 3, 2013 at 09:52:13

Well, since we're comparing languages, PowerShell comes in at half the line count of Python, and at a third of the readability:
$names = Get-Content ep.txt
$i = 0
Get-ChildItem *___* | ForEach-Object { 
  $_.MoveTo(($_.Name -replace "___", "_$($names[$i++])__"))
}

How To Ask Questions The Smart Way


Report •

#6
February 3, 2013 at 11:42:04

Well, at least i learned something! Never knew about wildcards in a replace operation - that's the part that confused me. I could see what it did, but I had never seen that before.

Report •

#7
February 3, 2013 at 11:47:21

Sadly you can only wildcard replace from the beginning and not from the end or it'd be easier to do what I want.

Report •


Ask Question