简体   繁体   English

枚举FOR / F语句的delims

[英]Enumerating the delims of a FOR /F statement

I have a FOR /F statement which I want it to enumerate the delims the command is parsing. 我有一个FOR / F语句,希望它枚举命令正在解析的delims。 For example: 例如:

FOR /F "delims=," %%A IN ("This,is,a,comma,delimited,sentence") DO (
    some command to enumerate delims
)
:OUT

I want it to account for each delimited item in that sentence. 我希望它解释该句子中每个定界的项目。 In this case it would output 6 在这种情况下,它将输出6

EDIT: I know the long way would be to do a check on each one.. but I'm trying to avoid that method: 编辑:我知道很长的路要走就是对每个检查..但我试图避免这种方法:

IF %%A == [] SET enum=0 && GOTO:OUT
IF %%B == [] SET enum=1 && GOTO:OUT

etc. 等等

There is NO way to directly enumerate items in a FOR /F "delims=..." command. 没有方法可以直接枚举FOR / F“ delims = ...”命令中的项目。 The usual way to do that is via a loop that count one item, eliminate it from the sentence and repeat while there was a counted item. 通常的方法是通过循环计算一个项目,将其从句子中删除,然后在有一个项目被计数时重复执行。

However, depending on the specific delimiter and the rest of characters in the sentence, you may use a FOR command (with no /F option) that will REPEAT its code with each item separated BY THE STANDARD BATCH DELIMITERS, that are comma, semicolon and equal-sign, besides spaces. 但是,根据特定的分隔符和句子中其余字符的不同,您可以使用FOR命令(不带/ F选项),该命令将使用标准批分隔符分隔的每个项目(用逗号,分号和等号,除了空格。 In your particular example: 在您的特定示例中:

SET ENUM=0
FOR %%A IN (This,is,a,comma,delimited,sentence) DO SET /A ENUM+=1

directly count the number of comma-separated items. 直接计算以逗号分隔的项目数。 If the delimiter is a character other than comma, semicolon or equal-sign, a possible solution is a three steps method: 如果定界符不是逗号,分号或等号之外的字符,则可能的解决方案是三步方法:

1- Replace spaces, comma, semicolon and equal-sign for another know character(s).
2- Replace the delimiter for any Batch standard delimiter (space, comma, etc).
3- Use a simple FOR to directly enumerate the items.

There IS a way to directly enumerate items in a FOR /F "delims=..." command. 有一种方法可以直接枚举FOR / F“ delims = ...”命令中的项目。
You only need to insert some newlines into the string. 您只需要在字符串中插入一些换行符即可。

setlocal EnableDelayedExpansion
set LF=^


rem ** Two empty lines are required

set count=0
FOR /F "tokens=* delims=" %%a in ("item1!LF!item2!LF!item3") DO (
  set /a count+=1
  echo !count!: "%%a"
)
echo(
set "CSV=This,is,a,comma,delimited,sentence"
echo Or with comma separeted text: !CSV!
for %%L in ("!LF!") do set "CSV=!CSV:,=%%~L!"
set count=0
FOR /F "tokens=* delims=" %%a in ("!CSV!") DO (
  set /a count+=1
  echo !count!: "%%a"
)

Aacini's suggestion to use a simple FOR instead of FOR /F is a good solution, unless the string might contain wildcard characters * or ? Aacini建议使用简单的FOR代替FOR / F是一个很好的解决方案,除非字符串可能包含通配符*? . The ? ? character could be protected by search and replace, but there is no efficient way to replace * in batch. 字符可以通过搜索和替换来保护,但是没有有效的方法来批量替换*

If you run into the wildcard problem then you can revert to using FOR /F in a loop to parse one word at a time. 如果遇到通配符问题,则可以恢复为在循环中使用FOR / F一次解析一个单词。 Most people use GOTO to accomplish the loop because you have no way of knowing how many words you will find. 大多数人使用GOTO来完成循环,因为您无法知道会发现多少个单词。 But GOTO is relatively slow. 但是GOTO相对较慢。 You can achieve a significant performance boost by using an outer FOR loop (not FOR /L) with an arbitrarily large number of items. 通过将外部FOR循环(不是FOR / L)与任意多个项目一起使用,可以显着提高性能。 Within the body you can exit the loop with a GOTO whenever there are no more words. 在体内,只要没有更多的单词,您都可以使用GOTO退出循环。 If the loop falls through without exhausting the words, you can use a GOTO to restart the loop. 如果循环失败而没有用完所有单词,则可以使用GOTO重新启动循环。 An outer loop with 100 items will only perform 1 GOTO per 100 parsed words. 具有100个项目的外部循环每100个解析的单词仅执行1个GOTO。

@echo off
setlocal enableDelayedExpansion
set "str=This,is,a,comma,delimited,sentence"
set "L10=1 2 3 4 5 6 7 8 9 0"
:loop - The outer FOR loop can handle 100 words before a single GOTO is needed
for %%. in (%L10% %L10% %L10% %L10% %L10% %L10% %L10% %L10% %L10% %L10%) do (
  for /f "tokens=1* delims=," %%A in ("!str!") do (
    echo %%A
    if "%%B" == "" goto :break
    set "str=%%B"
  )
)
goto :loop
:break

As with all FOR loops, you must worry about corruption of ! 与所有FOR循环一样,您必须担心!损坏! and ^ if delayed expansion is enabled when the %%A variable is expanded. 如果扩展%% A变量时启用了延迟扩展,则为^

FOR /L should not be used for the outer loop because FOR /L always finishes counting all iterations, even if you use GOTO within the body. FOR / L不应用于外部循环,因为即使您在体内使用GOTO,FOR / L也会始终完成对所有迭代的计数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM