Discussion forum for all Windows batch related topics.
Moderator: DosItHelp
-
nnnmmm
- Posts: 141
- Joined: 26 Aug 2017 06:11
#1
Post
by nnnmmm » 30 Aug 2017 04:31
i need an internal sub or external type batch sub that can extract a string from number N to the end of the string, it must handle % \ , . :: " :
I prefer an internal sub at the moment.
Code: Select all
@ECHO OFF
SET IN=%C1%\12345
CALL STRLEN IN N
ECHO %IN% %N%
PAUSE
returns \12345 6, and not 10, so this doesnt work.
-----------------------------------
Code: Select all
STRLEN.BAT has from this website
:STRLEN
( SETLOCAL ENABLEDELAYEDEXPANSION
SET "STR=A!%~1!"
SET "LEN=0"
FOR /L %%A IN (12,-1,0) DO (
SET /A "LEN|=1<<%%A"
FOR %%B IN (!LEN!) DO IF "!STR:~%%B,1!"=="" SET /A "LEN&=~1<<%%A"
)
)
( ENDLOCAL & REM RETURN VALUES
IF "%~2" NEQ "" SET /A %~2=%LEN%
)
EXIT /B
-
jeb
- Expert
- Posts: 1055
- Joined: 30 Aug 2007 08:05
- Location: Germany, Bochum
#2
Post
by jeb » 30 Aug 2017 05:14
The strlen function works and it's being right to say "6".
As SET IN=%C1%\12345 results into setting \12345 to "IN".
The %C1% will be expanded to the content of the C1 variable, but in your case it seems to be empty.
To set the variable use this
I added also quotes to avoid problems with trailing spaces
-
aGerman
- Expert
- Posts: 4678
- Joined: 22 Jan 2010 18:01
- Location: Germany
#3
Post
by aGerman » 30 Aug 2017 05:21
There are rules for string literals in a batch script that define how you have to escape special characters. (You'll find them a hundred times in the internet, e.g.
http://www.robvanderwoude.com/escapechars.php). Percent signs have to be doubled. Otherwise the command interpreter will try to expand %C1% to a variable value.
Steffen
-
nnnmmm
- Posts: 141
- Joined: 26 Aug 2017 06:11
#4
Post
by nnnmmm » 30 Aug 2017 07:37
Code: Select all
SetLocal EnableExtensions EnableDelayedExpansion
@ECHO OFF
SET K1=C:\AA.TXT
FOR /F "DELIMS=" %%V IN ('TYPE "%K1%"') DO (
SET VV=%%V
SET DS1=5
IF "!VV:~0,1!"=="%%" (
CALL C:\STRLEN.BAT "!VV!" LEN
SET DS2=!LEN!
ECHO !VV:~!%DS1%!,!%DS2%!!
ECHO !VV:~!DS1!,!!DS2!!!
ECHO.
)
)
PAUSE
-------------
AA.TXT has
%C1%\ABC DDDDD.EXE
%C1%\FFFDDDDDDDDD.TXT
SFSDFS FSDFSDFSDF.EXE
G11111 2 2 2222.EXE
dumb of me, SET IN=%C1%\12345
i oversimplied the problem, i think strlen.bat changes some kind of state, i dont know what it is
the script flow is simple, maybe you can help a few crucial things after this point. i need to seperate %ggg%'s in the text.
-
Squashman
- Expert
- Posts: 4486
- Joined: 23 Dec 2011 13:59
#5
Post
by Squashman » 30 Aug 2017 11:36
You are essentially trying to do Delayed Delayed Expansion. Yes you read that correctly and no you can't do that.
But I am having a hard time understanding why you feel the need to get the length of the string to accomplish what you are trying to do.
I also do understand what you mean by this based on your examples.
nnnmmm wrote:i need to seperate %ggg%'s in the text.
-
aGerman
- Expert
- Posts: 4678
- Joined: 22 Jan 2010 18:01
- Location: Germany
#6
Post
by aGerman » 30 Aug 2017 11:43
Do you know what an
XY Problem is?
First let me answer your question.
Code: Select all
@echo off &setlocal DisableDelayedExpansion
SET "K1=C:\AA.TXT"
FOR /F "DELIMS=" %%V IN ('TYPE "%K1%"') DO (
SET "VV=%%V"
SET "DS1=5"
setlocal EnableDelayedExpansion
IF "!VV:~0,1!"=="%%" (
CALL "C:\STRLEN.BAT" "VV" "LEN"
SET "DS2=!LEN!"
for /f "tokens=1,2" %%i in ("!DS1! !DS2!") do (
ECHO !VV:~%%i,%%j!
)
ECHO.
)
endlocal
)
PAUSE
2 Questions that I have:
1)Why do you compute the length? If you want to get the substring from a certain position till the end simply leave out the second number like
ECHO !VV:~%DS1%!If you define DS1 outside of the loop (and there is no reason why you defined it inside) it should exactly work like that.
2) If you just want to extract the file name out of a path (as your example states) then it doesn't make sense to apply string manipulations. Why don't you use the manipulators of FOR variables instead?
FOR /F "DELIMS=" %%V IN ('TYPE "%K1%"') DO echo %%~nxVSteffen
-
Squashman
- Expert
- Posts: 4486
- Joined: 23 Dec 2011 13:59
#7
Post
by Squashman » 30 Aug 2017 12:11
aGerman wrote:2) If you just want to extract the file name out of a path (as your example states) then it doesn't make sense to apply string manipulations. Why don't you use the manipulators of FOR variables instead?
FOR /F "DELIMS=" %%V IN ('TYPE "%K1%"') DO echo %%~nxV
Steffen
BINGO!
-
nnnmmm
- Posts: 141
- Joined: 26 Aug 2017 06:11
#8
Post
by nnnmmm » 30 Aug 2017 14:29
AA.txt goes like this, it is a menu that i collected from all kinds of things
type 1. path1\program.exe
tyep 2. path2\path3\program.exe
type 3 path4\program.exe arg1 arg2 arg3....
type 4 path5\path6\program.exe arg1 arg2 arg3....
%C1%\FILE SPLITTER V5.0.1189.EXE
%Q1% setdisplay 1920 1080 32 -updatereg
%Q1% setdisplay 1680 1050 32 -updatereg
%Q1% setdisplay 1280 1024 32 -updatereg
%C1%\"CLEARTYPE TOGGLER.EXE" ON C 1000
%C1%\"CLEARTYPE TOGGLER.EXE" OFF
%C1%\TurnFlash.exe on
%C1%\TurnFlash.exe off
%C2%\End It All 3\ENDITALL.EXE
%C2%\WaveEditor\"ctwave v3.1.exe" -o
%C1%\CPUZ-x32.EXE
%C1%\GPUZ.EXE
%C2%\PDF\SumatraPDF-x32.exe
%C1%\USB DEVICE VIEW.EXE
%C1%\ipnetinfo.exe
%C1%\Who is This Domain.exe
%C1%\AdapterWatch - Info of your network adapters.exe
%Q2%\RegScanner.exe
.
.
my plan is like this.
menu.txt
menu number. program name (without a path, it is too long to display)
heavy filtering is needed.
set /p input=
execute a program by entering the number
and plus, i need to learn batch
i may understand how to read batch subs for now, just a little bit. but not quite able to write it. been 2 ~ 3 days since i made my 1st internal sub.
i will try to write this with some pointers and some syntax directions.
%ggg%'s in the text. sorry about this.
i meant any arbitray variable names in the aa.txt
-
Squashman
- Expert
- Posts: 4486
- Joined: 23 Dec 2011 13:59
#9
Post
by Squashman » 30 Aug 2017 15:30
My best advice to people is too always give an exact representation of your input and an exact representation of what you want for your output without obfuscating the input to the point of causing other problems. In a couple of your questions your examples were so obscure you sent the people helping you on a wild goose chase because you could not clearly state what your script needed to do based on your input.
-
aGerman
- Expert
- Posts: 4678
- Joined: 22 Jan 2010 18:01
- Location: Germany
#10
Post
by aGerman » 30 Aug 2017 15:51
Because I don't know what you saved in variables like %C1% or %Q1% let me show you a fully commented example that should work for you as well.
AA.txt (in the same directory along with your batch file)
Code: Select all
"%path1%\cmd.exe" /k color 0a
"%path2%\explorer.exe" /select,"%~f0"
"iexplore.exe" www.dostips.com
Batch file (all of the code in one file)
Code: Select all
@echo off &setlocal DisableDelayedExpansion
REM define the variables used in AA.txt
set "path1=C:\Windows\System32"
set "path2=C:\Windows"
REM option /n prepends the line number and a colon to every line read
REM "^" matches all lines that have a begin of line (so this means every line)
for /f "tokens=1* delims=:" %%i in ('findstr /n "^" "AA.txt"') do (
REM pass the line number (%%i) and the rest of the line (%%j) to the :print label
call :print %%i %%j
REM create an associative array; the CALL before SET leads to expand variables in the line read
call set "cmmd%%i=%%j"
)
REM ECHO directly followed by an opening parenthesis is the safest way to print a blank line
echo(
REM place a label in order to be able to prompt the user again if the input was invalid
:input_loop
REM prompt the user and read the input
set "input="
set /p "input=Enter a number: "
REM check if the variable was part of the associative array; prompt the user again if not
if not defined cmmd%input% goto input_loop
REM Enable delayed expansion to easily expand nested variables
setlocal EnableDelayedExpansion
REM run the selected command aynchronously
start "" !cmmd%input%!
endlocal
pause
exit /b
:print
REM process the first and the second parameter
REM note! that every string separated by a command delimiter comes in as separate parameter, e.g for a passed
REM 1 "C:\Windows\System32\cmd.exe" /k color 0a
REM the 1 is in %1, "C:\Windows\System32\cmd.exe" is in %2, /k is in %3, etc.
REM note! that parameters that are enclosed in quotation marks are always treated as one parameter even if they contain spaces
REM this is the reason why the path is always enclosed in quotation marks in AA.txt because we always need it completely in %2
REM the ~nx modifier expands the second parameter to file name and extension only
echo Type %1. %~nx2
exit /b
Steffen
-
nnnmmm
- Posts: 141
- Joined: 26 Aug 2017 06:11
#11
Post
by nnnmmm » 02 Sep 2017 06:53
Code: Select all
CALL C:\BATCH\SUB-LIB1.BAT STRLEN1 VV LEN
SET DS2=!LEN!
ECHO it works !DS1! !DS2! in here but
ECHO !VV:~!DS1!,!DS2!! but not in here, because it doesnt seem to work in another! !'s
so this is it
FOR /F "TOKENS=1,2" %%A in ("!DS1! !DS2!") DO (
ECHO it works !VV:~%%A,%%B!
)
this type of a variable tranfer is insanely difficult.
i lost the batch file making for this menu for many days after i saw those lines.
Code: Select all
>ECHO !VV:~%DS1%!
ECHO !VV:~%A%!
ECHO.
"DELIMS="
CALL ECHO:%%P1:~0,%AA%%%
.
ECHO !VV:~%A%! is the one of those things like the above that there is no way to guess at 1st time. but thanks for showing me this.