Thanks to everyone who replied. Apologies for not responding sooner.
@npocmaka
Imho, the priority of for /f options
in most cases is:
- usebackq
- skip
- delims
- eol
- tokens
Skip will count blank lines and lines beginning with eol. Delims is next because for /f has to know on what characters to split the line into tokens. Next, if the first character of the first token is eol, then the line is skipped. And lastly, the line is split into tokens.
Thanks to Dave for setting me straight.
@Jeb
You wrote:
Code: Select all
set "line=X"
for /L %%n in (1 1 10) do set "line=!line:~0,500!!line:~0,500!"
(
for /L %%n in (1 1 100) do (
set /p ".=!line!" < nul
)
echo param2 param3
) > long.txt
You created var line containing 100k Xs. I understand the second part where line contained 1k Xs and you printed it out 10 times. It’s the first part that has me stumped. You expanded line like an accordian twice, and it magically filled up with 1k Xs. I’ve never seen this done before. Please explain what’s going on here, and more importantly, how you figured out how to do it. My growing suspicion is that you have spooky powers.
@Foxidrive
I wanted to find the last token because I was looking for an alternative method to trim leading and trailing whitespace from a string. Here’s a working draft:
Code: Select all
@echo off & setlocal enableextensions disabledelayedexpansion
:: nasty string padded with lots of tabs and spaces
set ^"str= ^^^" ^^^&^^ ^"^^^&^"^& !^^!^^^^! %% %%OS%% ^"
:: must double quotes in ddx
if not defined str (>&2 echo(string not defined & goto die
) else set "str=%str:"=""%"
:: count tokens in string
set "nth=0"
:loop
set /a nth+=1
for /f tokens^=%nth%^ eol^= %%A in ("%str%") do goto loop
set /a nth-=1
if %nth% equ 0 (>&2 echo(string consists entirely of whitespace
goto die) else if %nth% equ 1 (
:: edge case of 1 token in string
for /f tokens^=1^ eol^= %%B in ("%str%") do (set "str=%%B"
setlocal enabledelayedexpansion
rem safe to undouble quotes in edx
echo([!str:""="!]
endlocal & goto end))
:: store l&r-trimmed last token in var
for /f tokens^=%nth%^ eol^= %%B in ("%str%") do set "nthtoken=%%B"
:: get length of tail (start of last token to end of string)
set /a nth-=1
for /f tokens^=%nth%*^ eol^= %%C in ("%str%") do (set "tail=%%D"
for /f skip^=1^ delims^=:^ eol^= %%E in ('set tail ^^^& echo( ^| ^
findstr /o "^"') do set /a lentail=%%E-7)
:: chop off leading whitespace with "tokens=*" trick
for /f tokens^=*^ eol^= %%F in ("%str%") do set "str=%%F"
setlocal enabledelayedexpansion
:: Str[0..-LenTail] + NthToken = L&R Trimmed Str
set "str=!str:~0,-%lentail%!!nthtoken!"
:: safe to undouble quotes in edx
echo([!str:""="!]
endlocal & goto end
:die
(call)
:end
endlocal & goto :eof
I’m liking this approach much more than my previous efforts at coming up with a viable alternative solution to this problem, but it still has a ways to go. I want to get rid of the goto loop and I’m not happy about having to find the length of the tail. The former can be eliminated with chicanery, but the latter is proving a hard nut to crack.
If anyone would like to suggest refinements to my code, please feel free to post them here.
Toodles!
- SB