I can't get a variable of loop - batch-file

I am trying to write a simple batch file
The script gets namefile for the file "dump" and I split the string, but i can't display the variable !!
for /r %%a in (dump\*) do (
set file=%%a
for /f %%i in ("%%a") do (
for /F "tokens=1 delims=-" %%d IN ("%%~ni") do set db=%%d
)
echo %db%
)
pause
Any ideas?
Thanks for your help.

try setting the setlocal ENABLEDELAYEDEXPANSION and swapping the var with exclamation marks instead, see below:
setlocal ENABLEDELAYEDEXPANSION
for /r %%a in (dump\*) do (
set file=%%a
for /f %%i in ("%%a") do (
for /F "tokens=1 delims=-" %%d IN ("%%~ni") do set db=%%d
)
echo !db!
)
pause

Related

IN ECHO statement how can i print all the columns without defining multiple output parameters

for /f " tokens=%i%-%j% delims=," %%a in (%input%) DO (
(ECHO %%a %%b %%c %%d %%e %%f %%g %%h %%i %%j)>>%output%
)
"delims=" will force no delimiter and use full string making each line %%a instead of each word, delimited by ,.
for /f "delims=" %%a in (%input%) DO ECHO %%a >>%output%
If you would like to get rid of the , simply replace it.
#echo off
setlocal enabledelayedexpansion
for /f "delims=" %%a in (%input%) DO ( set string=%%a
set string=!string: =,!
ECHO !string! >> %output%
)
endlocal
According to your comments, the following should do exactly, what you want: multiple spaces are reduced to one delimiter, no delimiters at the end of a line.
#echo off
setlocal enabledelayedexpansion
(for /f "delims=" %%a in (input.txt) do (
set "new="
for %%b in (%%a) do (
set "new=!new!,%%b"
)
echo !new:~1!
))>output.txt
Because your ? characters may be problematic with some solutions, the following may do what you require:
#Echo Off
Set "input=input.txt"
Set "output=output.txt"
Set "_="
(For /F "UseBackQ Delims=" %%A In ("%input%"
) Do Set "_="&Call :Sub %%A&Call Echo(%%_:~1%%)>"%output%"
If Not Defined _ Del "%output%"
Exit /B
:Sub
If "%1"=="" GoTo :EOF
Set "_=%_%,%1"
Shift&GoTo :Sub

Batch file that renames files numerically not working

I have a folder into which I do a print to file option and it saves my print job as a pcl file. The software I use to do the print to file names each file in following manner: GUID.XX.pcl where XX is a number.
Example:
{2E594442-FDF9-4992-88DA-EA4ED2811ECD}.6.pcl
{2E594442-FDF9-4992-88DA-EA4ED2811ECD}.7.pcl
{2E594442-FDF9-4992-88DA-EA4ED2811ECD}.8.pcl
{2E594442-FDF9-4992-88DA-EA4ED2811ECD}.9.pcl
{2E594442-FDF9-4992-88DA-EA4ED2811ECD}.10.pcl
{2E594442-FDF9-4992-88DA-EA4ED2811ECD}.11.pcl
What I want to do is rename the files so that they look like this:
1.pcl
2.pcl
3.pcl
and so on.
Here is the batch I use:
for %%a in (*.pcl) do (
set /a i+=1
ren "%%a" "!i!.new"
)
ren *.new *.pcl
This works but the problem is,in the example I gave above
It renames
{2E594442-FDF9-4992-88DA-EA4ED2811ECD}.10.pcl to 1.pcl
and
{2E594442-FDF9-4992-88DA-EA4ED2811ECD}.6.pcl to 3.pcl
I need it to rename
{2E594442-FDF9-4992-88DA-EA4ED2811ECD}.6.pcl to 1.pcl
and
{2E594442-FDF9-4992-88DA-EA4ED2811ECD}.10.pcl to 5.pcl
It is basically seeing 10 before 6. Is there some way around this?
for /F "tokens=1-3 delims=." %%a in ('dir /B *.pcl') do (
set /A num=100+%%b
set "name[!num:~1!]=%%a.%%b.%%c"
)
for /F "tokens=2 delims==" %%a in ('set name[') do (
set /A i+=1
ren "%%a" "!i!.pcl"
)
If you want to use two digits in the new name, so the order be preserved in dir or for listings, modify the second part this way:
set i=100
for /F "tokens=2 delims==" %%a in ('set name[') do (
set /A i+=1
ren "%%a" "!i:~1!.pcl"
)
EDIT: I tested my code and it works correctly. This is the output of the test session:
C:\> dir /b
test.bat
{2E594442-FDF9-4992-88DA-EA4ED2811ECD}.10.pcl
{2E594442-FDF9-4992-88DA-EA4ED2811ECD}.11.pcl
{2E594442-FDF9-4992-88DA-EA4ED2811ECD}.6.pcl
{2E594442-FDF9-4992-88DA-EA4ED2811ECD}.7.pcl
{2E594442-FDF9-4992-88DA-EA4ED2811ECD}.8.pcl
{2E594442-FDF9-4992-88DA-EA4ED2811ECD}.9.pcl
C:\> test
C:\> dir /b
1.pcl
2.pcl
3.pcl
4.pcl
5.pcl
6.pcl
test.bat
C:\> type test.bat
#echo off
setlocal EnableDelayedExpansion
for /F "tokens=1-3 delims=." %%a in ('dir /B *.pcl') do (
set /A num=100+%%b
set "name[!num:~1!]=%%a.%%b.%%c"
)
for /F "tokens=2 delims==" %%a in ('set name[') do (
set /A i+=1
ren "%%a" "!i!.pcl"
)
not tested:
for %%a in (*.pcl) do (
for /f "tokens=2 delims=}" %%# in ("%%~nxa") do (
ren "%%~fa" "%%#"
)
)

search and replace string using batch commands

How can i search a string and replace it with a variable.
i would like to search version="1.37.0" but the version number could be anything. And there are two "version=" string in package.xml but i would like to replace second one.
how can i search version="x.x.x" and replace it with version="$variable"?
is there any one liner?
i did try to use something like this to search:
findstr "version="[0-9].[0-9].[0-9]" package.xml
and also same thing for desrciption="$variable1"
package.xml
<?xml version="1.0" encoding="utf-8"?>
<PackageManifest>
<Package name="audio"
description="something. . .."
version="1.37.0"
comment="">
</Package>
</PackageManifest>
ad hoc solution, but ...
Edited to adapt to comments
#echo off
setlocal enableextensions disabledelayedexpansion
rem Check input parameters. Needed the input file, the version and the description
if "%~3"=="" goto :eof
set "file=%~1"
set "newVersion=%~2"
set "newDescription=%~3"
rem Read the file into memory
for /f "tokens=1,* delims=:" %%a in ('findstr /n "^" "%file%"') do (
set /a "line=1000+%%a*10"
setlocal enabledelayedexpansion
for %%c in (!line!) do endlocal & set "l_%%c=|%%b"
)
rem %%a will search the required lines
rem %%c remove blanks at the start of the line
rem %%d get the key name
for /f "tokens=2,* delims=_=|" %%a in (
'set l_1 ^| findstr /i /r /c:"^[^<]*version=" /c:"description=" /c:"^[^<]*<Package"'
) do for /f %%c in ("%%b") do for /f "delims==" %%d in ("%%c") do (
if /i "%%d"=="description" ( set "value=%newDescription%" & set "newDescription="
) else if /i "%%d"=="version" ( set "value=%newVersion%" & set "newVersion="
) else if /i "%%d"=="<Package" ( set "packageLine=%%a" & set "value="
) else set "value="
if defined value ( setlocal enabledelayedexpansion
for /f "delims=" %%z in ("!value!") do ( endlocal
for /f tokens^=1^,2^,^*^ delims^=^" %%e in ("%%b") do set "l_%%a=|%%e"%%z"%%g"
)
)
)
rem Include the missing values
set /a "packageLine+=1"
if defined newDescription set "l_%packageLine%=| description="%newDescription%""
set /a "packageLine+=1"
if defined newVersion set "l_%packageLine%=| version="%newVersion%""
rem Output the changed information to console
for /f "tokens=1,* delims=|" %%a in ('set l_1') do echo(%%b
rem Save to file
>"%file%" (for /f "tokens=1,* delims=|" %%a in ('set l_1') do echo(%%b)
Try this :
#echo off
set $FindStr=Version="x.x.x"
set $ReplString=Version="y.y.y"
setlocal enabledelayedexpansion
for /f "delims=" %%a in ('type test.xml') do (
set $Ver=%%a
set $Ver=!$Ver: =!
If /i !$Ver!==%$FindStr% set $Ver=%$ReplString%
echo !$Ver! ) >> Output.xml
Very simplist but a good base
Edit :
This will ask for the version value of the second matched version=
#echo off
set "$FindStr=Version="
set $c=1
setlocal enabledelayedexpansion
for /f "delims=" %%a in ('type test.xml') do (
set $Ver=%%a
set $Ver=!$Ver: =!
If /i "!$Ver:~0,8!"=="%$FindStr%" (
if !$c! GTR 1 (
set /p "$NewVer=Enter New version : "
set $Ver=%$FindStr%!$NewVer!)
set /a $c+=1)
echo !$Ver! >> Output.xml)
The input file is text.xml and the ouputFile Output.xml

Order files list by batch

I have a long list of individual songs not in folders just songs, and I'd like to move them to the folder of theire artist. the songs are in the following format
artist - songname.flac
I can store them in a list, and echo it, but splitting the artist and songname in 2 vars, I can't seem to figure out.
Could someone help me with the splitting (or if you want even with the rest of the script)
this is what I have so far:
#echo off
setlocal enabledelayedexpansion
set N=0
for %%i in (*) do (
set Files[!N!]=%%~ni
set /a N+=1
)
for /l %%x in (1,1,%N%) do echo.!Files[%%x]!
pause
set SOURCE=c:\temp\test
for /f "delims=-. tokens=1,2" %%i in ('dir /b "%SOURCE%\*.flac"') do echo Artist : %%i Song : %%j
update for full script (got to check if it works with space and special chars in path) :
#echo off
setlocal enabledelayedexpansion
set SOURCE=c:\temp\test
set DESTINATION=c:\temp\test
for /f "tokens=*" %%i in ('dir /b "%SOURCE%\*.flac"') do call :OrderThatMess "%%i"
:OrderThatMess
set NAME=%1
for /f "tokens=1,2 delims=-. " %%j in (%1) do (
set ARTIST=%%j
set TITLE=%%k
if not exist "%DESTINATION%\%ARTIST%" (md "%DESTINATION%\%ARTIST%" )
copy %SOURCE%\%NAME% "%DESTINATION%\%ARTIST%\%TITLE%.flac"
)
#echo OFF &SETLOCAL ENABLEDELAYEDEXPANSION
for %%i in (*.flac) do (
set /a N+=1
FOR /f "tokens=1,2 delims=- " %%o IN ("%%~ni") DO (
set "FilesA[!N!]=%%~o"
set "FilesB[!N!]=%%~p"
)
)
for /l %%x in (1,1,%N%) do echo(!FilesA[%%x]! !filesB[%%x]!
Thanks for the answers ;) Thanks to Kayasax I fixed it
here is the full code:
#echo off
SETLOCAL ENABLEDELAYEDEXPANSION
set SOURCE=C:\music\folder\with\files\
for /f "tokens=1,2 delims=-" %%i in ('dir /b "%SOURCE%\*.flac"') do (
set "folder=%%i"
IF NOT EXIST "%SOURCE%\%%i" (
mkdir "%%i"
)
move "%SOURCE%\%%i-%%j" "%SOURCE%\!folder:~0, -1!\%%i-%%j"
)
pause

How to get a Substring from list of file names

I want to develop the following logic
Read all files in a directory
Extract the first part of the filename – this will be the partner name
Extract anything after the first underscore- this will be filename
Eg: ZZTEST_123_abc_doc.txt  ZZTEST is partner. 123_abc_doc.txt is the filename.
Below is the code I developed
#echo off
setlocal ENABLEDELAYEDEXPANSION
Set Test_Dir=C:\Axway\projects\Cardinal\dosscript\test
cd %Test_Dir%
for /r %%a in (*.*) do (
Set "fname1=%%~nxa"
echo Filename is :!fname1!
for /f "tokens=1 delims=_" %%i in ("!fname1!") do (
Set "partner=%%i"
echo Partner is :!partner!
Set "str_tmp=!partner!_"
echo !str_tmp!
call :strlength length !str_tmp!
echo !length!
set fname=!fname1:~%length%!
echo !fname1:~%length%!
)
)
goto :eof
:strlength
setlocal enableextensions
set "#=%~2"
set length=0
:stringLengthLoop
if defined # (set "#=%#:~1%"&set /A length+=1&goto stringLengthLoop)
endlocal && set "%~1=%length%"
GOTO :EOF
But the result is
ID_ZZRoutingID_filename.txt
Filename is :ZZRoutingID_ZZRoutingID_filename1.txt
Partner is :ZZRoutingID
12
Result: ID_ZZRoutingID_filename1.txt
The result should be ZZRoutingID_filename1.txt but i am getting
ID_ZZRoutingID_filename1.txt.
Please help
The purpose of the length calculation is not clear to me, but I would suggest adding an asterisk following the 1 in your for /f "tokens=1 delims=_". You would then get the "filename" you were looking for through %%j.
I tested it like this:
#echo off
setlocal EnableDelayedExpansion
set source=D:\Program Files\Somewhere
cd %source%
for /r %%i in (*.*) do (
for /f "tokens=1* delims=_" %%j in ( "%%~nxi" ) do (
echo partner: %%j
echo name: %%k
)
)
endlocal
If you do not need to recurse through sub-directories:
#echo off
set source=D:\Program Files\Somewhere
for /f "tokens=1* delims=_" %%i in ( 'dir "%source%" /b /a-d' ) do (
echo partner: %%i
echo filename: %%j
)
dir /b /a-d retrieves the list of a directory's content except its sub-directories:
D:\Program Files\Somewhere>dir /b /a-d
ZZTEST_123_456.txt
ABCDEF_890_FFF.doc
FOOBAR_567_###.zzz

Resources