How to use a substring in for loop of batch script? - batch-file

This is my first batch script. I want to convert a list of files and use a substring of the input filename (Day of year). However the substring part doesn't work:
SETLOCAL EnableDelayedExpansion
FOR %G IN (%dirInp%%station%???0.DAT) DO (
SET filInp="%G"
SET doy=!filInp:~-9,3! rem this doesn't work?
rem Convert Trimble GPS receiver observations to RINEX
%dirExe%teqc -tr d %G > %dirOut%%station%!doy!0.%yy%D
)
So, how should I do this?

In addition to #Stephan 's comment I've updated your code to make a minimal working example (MWE) using some abstact file paths and substring parameters.
Than I moved SETLOCAL EnableDelayedExpansion inside the FOR loop and now it works for me on Windows 7.
I also closed SETLOCAL EnableDelayedExpansion by endlocal (could be sensitive for further code excecution
#echo off
FOR %%G IN (C:\DirInput_StationA\201901.DAT C:\DirInput_StationB\201812.DAT) DO (
SETLOCAL EnableDelayedExpansion
SET "filInp=%%G"
SET "doy=!filInp:~-10,4!"
rem Convert Trimble GPS receiver observations to RINEX
REM Changed your call to echo of the vars
echo G: "%%G"; doy: "!doy!"
endlocal
)

Related

Batch file - can not read a variable

Making batch which generate previews (everything is fine with this part of code) and also rename files deleting everything after "_" in filename. For example ABAB_abab.png > ABAB.png
My code does not see a variable yy in the string: set zz=!xx:yy=! Perceives it like just two letters yy, not a variable. How to fix that?
Here is the script
setlocal enabledelayedexpansion
for %%a in ("*.png") do (
set xx=%%~na
set yy=_!xx:*_=!
set zz=!xx:yy=!
echo xx= !xx! #rem (okay, returns ABAB_abab)
echo yy= !yy! #rem (okay, returns _abab)
echo zz= !zz! #rem (wrong, returns ABAB_abab without any substitutions)
pause
)
endlocal
Thank you for help
Here's a quick example to show you a method of achieving another layer of expansion:
#Echo Off
SetLocal EnableExtensions DisableDelayedExpansion
For %%G In ("*.png") Do (
Set "xx=%%~nG"
SetLocal EnableDelayedExpansion
Set "yy=_!xx:*_=!"
For %%H In ("!yy!") Do Set "zz=!xx:%%~H=!"
Echo xx = "!xx!"
Echo yy = "!yy!"
Echo zz = "!zz!"
EndLocal
Pause
)
The doublequotes are included in the Echo commands only for better visualization should there be any spaces in your strings, they're not needed for any other purpose.
Please note, that this will not achieve your intention with any .png files whose basename begins with one or more underscores, _.

Looking for a script to rename multiple files with charactares already in filename

I have many files in many folders that I need to rename.
And example is
from cgs2016-09-05-05-40-34.xls
to cgs0905.xls
and
from cgs2016-09-06-05-40-34
to cgs0906.xls
etc
Any help would be greatly appreciated!
#Jamaz Try out the following code below on a sample of your files. Again please use it on a test sample of your files so it does not cause you issues if it makes a mistake. Thank you and please up-vote if this works for you.
setlocal enabledelayedexpansion
REM Collect list of file names in current directory that have the .xls file extension. Output to text file.
dir /b "*.xls" >xls.txt
REM For loop examines the text file for individual file names.
FOR /F "tokens=1" %%# in (.\xls.txt) do (
REM SET variable "#" to equal "token"
Set "token=%%#"
REM Extract the first 3 characters (year) from the file name and set is to variable "token"
Set "tokenchar=!token:~0,3!"
REM Extract the month characters from the file name and set the variable as "tokenmonth"
Set "tokenmonth=!token:~8,2!"
REM Extract the day characters from the file name and set the variable as "tokenday"
Set "tokenday=!token:~11,2!"
ren "%%#" "!tokenchar!!tokenmonth!!tokenday!.xls"
echo %%#
)
Pause
not the best way, but works for your examples:
#echo off
setlocal enabledelayedexpansion
for %%x in (*.xls) do (
set "filename=%%x"
ECHO ren "%%x" "!filename:~0,3!!filename:~8,2!!filename:~11,2!.xls"
)
remove the ECHO if output is ok.
Because the last nineteen characters, date and time stamp, are more likely to be constant than the first three, (especially over multiple folders), I'd change both the previous answers to cater for that rationale.
#Echo Off
SetLocal EnableDelayedExpansion
(Set _rf=C:\Users\jamaz\TestDir)
(Set _fe=xls)
If Not Exist "%_rf%\" Exit/B
For /R "%_rf%" %%I In (*.%_fe%) Do (Set "_fn=%%~nI"
Echo=Ren "%%I" "!_fn:~,-19!!_fn:~-14,2!!_fn:~-11,2!%%~xI")
Timeout -1 1>Nul
EndLocal
Exit/B
As the OP was not clear about whether the code was for multiple same level folders or subfolders rooted from a single location, I went for the latter as the previous responses had already covered that.
Change your chosen file path and extension on lines 4 and 5
If you are happy with the console output, remove echo= from line 10 and delete line 11

Windows Batch:string replacement

The following batch file accepts a parameter which is a path and filename.
#echo off
SETLOCAL ENABLEDELAYEDEXPANSION
SET filename=%~1
echo !filename!
ENDLOCAL
The filename, when received as a parameter will always be formatted using forward slashes.
In order to replace the forwardshlashes with backslashes, I tried this:
SET filename=!filename:/=\!
But that's not working.
What is the simplest way to do string replacement in a windows batch file?
Thanks
First of all you need to remove the space after =:
SET filename=%~1
Otherwise the space will become part of your variable.
To replace / with \ you have to use % instead of !:
SET filename=!filename:/=\!
Further, there is nothing in your code that would require ENABLEEXTENSIONS so you can skip it.
EDIT:
This is my code of something.bat:
#ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
SET file=%~1
SET file=!file:\=/!
ECHO !file!
Calling the something.bat ABC/DEF/GHI results in the output ABC\DEF\GHI.
You have a problem when you set the variable
v...v. Initial and ending spaces included in value
SET filename = %~1
^........ Space included in variable name
As the variable is not %filename%, but %filename %, your replacement fails. For a string replacement approach you can use
#echo off
setlocal enableextensions disabledelayedexpansion
set "filename=%~1"
set "filename=%filename:/=\%"
echo %filename%
or, still better, this case can be solved using argument modifiers
#echo off
setlocal enableextensions disabledelayedexpansion
set "filename=%~f1"
echo %filename%

How define a big array in Batch?

I want to define a big array (>400 keys) in batch, but when I execute my script the windows close. I use this setting:
set FILE_LIST=(filename1.xxx [...] filename450.yyy)
Some help? Thx
A Windows Batch file have a limit in the value of each variable to 8192 characters, including the name of the variable and the equal sign. If the value of each "filename#.xxx " have 16 characters, you may store up to 8192/16=512 file names in one variable; to do that, you must use Batch commands. For example:
#echo off
setlocal EnableDelayedExpansion
set "FILE_LIST="
for /L %%i in (1,1,450) do set "FILE_LIST=!FILE_LIST!filename%%i.xxx "
echo FILE_LIST=%FILE_LIST%
Please, note that previous variable is a list, NOT and array. To define an array, use this method:
#echo off
setlocal EnableDelayedExpansion
for /L %%i in (1,1,450) do set "FILE_ARRAY[%%i]=filename%%i.xxx"
echo FILE_ARRAY:
set FILE_ARRAY
There is a limit of 64 MegaBytes for the total space occupied by all variables.
For a detailed description of arrays and other data structures in Batch files, see: Arrays, linked lists and other data structures in cmd.exe Batch script
EDIT: Reply to the comments
The Batch file below assume that there is one file name per line in the .txt file, and that file names does not include exclamation marks:
#echo off
setlocal EnableDelayedExpansion
rem Load the .txt file in FILE_ARRAY elements:
set num=0
for /F "delims=" %%a in (fileList.txt) do (
set /A num+=1
set "FILE_ARRAY[!num!]=%%a"
)
rem Process the FILE_ARRAY elements:
for /L %%i in (1,1,%num%) do echo Processing: %%i- "!FILE_ARRAY[%%i]!"
I finaly use this way:
set FILE_ARRAY[0]=filename1.xxx
set FILE_ARRAY[1]=filename2.yyy
set FILE_ARRAY[2]=filename3.zzz
for /F "tokens=2 delims==" %%i in ('set FILE_ARRAY[') do (
echo %%i
)
Thanks for your answers.
Seems like you might be hitting a batch file limitation (link), The following link describes a WA for this issue as dumping what you want in a var into a file, then reading that file back in when you need that massive var.
Ah batch, and your endless workarounds...

How do you use SETLOCAL in a batch file?

How do you use setlocal in a batch file? I am just learning scripting and would like it explained to me in very simple terms.
I have a script that stops and says < was unexpected at this time it may have something to do with not having any setlocal statements in the script.
You make the first line SETLOCAL. This example is from the linked article below:
rem *******Begin Comment**************
rem This program starts the superapp batch program on the network,
rem directs the output to a file, and displays the file
rem in Notepad.
rem *******End Comment**************
#echo off
setlocal
path=g:\programs\superapp;%path%
call superapp>c:\superapp.out
endlocal
start notepad c:\superapp.out
The most frequent use of SETLOCAL is to turn on command extensions and allow delayed expansion of variables:
SETLOCAL ENABLEEXTENSIONS ENABLEDELAYEDEXPANSION
For more info on SETLOCAL see the Command Line Reference at Microsoft TechNet.
Direct link to Setlocal
Suppose this code:
If "%getOption%" equ "yes" (
set /P option=Enter option:
echo Option read: %option%
)
Previous code will NOT work becase %option% value is replaced just one time when the IF command is parsed (before it is executed). You need to "delay" variable value expansion until SET /P command had modified variable value:
setlocal EnableDelayedExpansion
If "%getOption%" equ "yes" (
set /P option=Enter option:
echo Option read: !option!
)
Check this:
set var=Before
set var=After & echo Normal: %var% Delayed: !var!
Guess what the output is...
Try this:
SET PATH=%PATH%;%~dp0;
This will get your local folder your are running the batch from and add it to the current path.
example: if your are running a .bat or .cmd from d:\tools\mybatch.bat
it will add d:\tools to the current path so that it may find additional files on that folder.

Resources