environment variable string substitution

The command processor has some handy features that allow you to manipulate environment variables on the fly.  For example, you can substitute one sub-string for another like this:

   echo %myvar:sub1=sub2%
   echo %time:0=-%

The second command would replace all "0"s with "-"s in the current system time.

You can also retrieve portions of the environment variable like this:

   echo %time:~3,5%

This would display 5 characters of the system time begining at character 3, so if:

   echo %time%

returns "01:23:45.67" then the previous command would return "23:45".

The big question is: how do you do both *without* setting a second environment variable to do it?

For example, suppose I want the middle 5 characters of the time (as above) but I also want to replace the colon(:) with an X instead?

I already know I can do this:

   set temp=%time:~3,5%
   echo %temp::=X%

this is what I am trying to avoid.  :)  Thanks!
LVL 33
Who is Participating?
oBdAConnect With a Mentor Commented:
Sorry, it's just not possible. You can either substitute characters or retrieve a substring, but not both at the same time (not even with delayed expansion).
You can use the ampersand to put it into a single line like that (you shouldn't use Temp; that contains the path to the temporary directory):

set MyTime=%Time:~3,5% & set MyTime=%MyTime::=X%
echo [%MyTime%]

Why exactly do you want to get around the second variable?
knightEknightAuthor Commented:
Thanks oBdA, yes I am familiar with all that...

>> Why exactly do you want to get around the second variable?

Because I am an anal geek.  Yep, that about sums it up.  Just wanted to verify what I already suspected, thanks!
knightEknightAuthor Commented:

  for /f "delims=." %t in ('echo %time::=%') do echo %t

This technically does what I want, but is more trouble than its worth to maintain.
Cloud Class® Course: Microsoft Exchange Server

The MCTS: Microsoft Exchange Server 2010 certification validates your skills in supporting the maintenance and administration of the Exchange servers in an enterprise environment. Learn everything you need to know with this course.

What exactly is it you want?
Seems like you want to echo the current time, but without the hundredth seconds?
That can be done without character substitution as well:
for /f "tokens=1-3 delims=:," %%a in ("%time%") do echo %%a%%b%%c
Then you probably want to print this several time in a script? Why not use a subroutine:

@echo off
:: ... Some batch script
call :echotime
sleep 2
call :echotime
:: ... Some batch script

goto leave
:: *** subroutine EchoTime
:: *** echoes the current time and returns
for /f "tokens=1-3 delims=:," %%a in ("%time%") do echo %%a%%b%%c
goto :eof

knightEknightAuthor Commented:
Actually, it is simpler than that.  All I'm trying to do is rename some files per the current date and time.  I have a script that I tested yesterday afternoon and it worked fine, it renamed  *.log  to  *.log.date_time

specifically the command expanded to this:  ren  filename.log  filename.log.04262005_154427

But when the script ran overnight it failed because the %time% variable does not have a leading 0 before noon, so the rename command expanded to this:    ren  filename.log  filename.log.04272005_ 73152

and the space messed up the rename command.  Stand by and I'll post new code.
knightEknightAuthor Commented:
this does it:

   for /f "tokens=1,2,3,4,5,6,7,8* delims=/:_." %t in ('echo %time: =0%_%date:~4%') do ren *.log *.log.%z%y%x_%t%u%v

In that case, I'd suggest putting the date variable into reverse order, that is yyyymmdd; makes for easier sorting.
You can do that easily with a for /f command as well; the main configuration involves your date delimiter and the d/m/y order.
This should give you the basic idea:

for /f "tokens=1-3 delims=/" %%a in ("%date%") do (
  set mm=%%a
  set dd=%%b
  set yy=%%c
set MyDate=%yy%%mm%%dd%

Adding leading zeroes to the hour is similar:

for /f "tokens=1-3 delims=:," %%a in ("%time%") do (
  set hh=%%a
  set mi=%%b
  set ss=%%c
if %hh% LSS 10 set hh=0%hh%
set MyTime=%hh%%mi%%ss%
knightEknightAuthor Commented:
actually, I mis-typed my original requirements, I should have specified this:

   ren  filename.log  filename.log.20050426_154427


   ren filename.log filename.log.yyyymmdd_hhMMss

but we've got it working now.  Thanks!
knightEknightAuthor Commented:
  for /f "tokens=1,2,3,4,5,6,7,8* delims=/:_." %t in ('echo %time: =0%_%date:~4%') do ren *.log *.log.%z%y%x_%t%u%v

this puts the date in the proper order and does not require extraneous variables beyond the scope of the for-statement.
knightEknightAuthor Commented:
final version, simplified a bit:

   for /f "tokens=1-6 delims=/:." %t in ('echo %date:~4%.%time: =0%') do ren *.log *.log.%v%t%u_%w%x%y
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.