枚举 FOR /F 语句的分隔符

发布于 2025-01-03 17:59:15 字数 402 浏览 1 评论 0原文

我有一个 FOR /F 语句,我希望它枚举命令正在解析的分隔符。例如:

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

我希望它能够解释该句子中的每个分隔项。在这种情况下,它将输出 6

编辑:我知道很长的路要对每一个进行检查..但我试图避免这种方法:

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

等等。

I have a FOR /F statement which I want it to enumerate the delims the command is parsing. 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

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

嗫嚅 2025-01-10 17:59:15

无法直接枚举 FOR /F“delims=...”命令中的项目。通常的方法是通过一个循环来计算一个项目,将其从句子中删除,并在存在已计算的项目时重复。

但是,根据特定的分隔符和句子中的其余字符,您可以使用 FOR 命令(不带 /F 选项),该命令将重复其代码,其中每个项目由标准批量分隔符分隔,即逗号、分号和等号,除了空格。在您的特定示例中:

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

直接计算逗号分隔项目的数量。如果分隔符是逗号、分号或等号以外的字符,可能的解决方案是三步方法:

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 NO way to directly enumerate items in a FOR /F "delims=..." command. 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. 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.
情痴 2025-01-10 17:59:15

有一种方法可以直接枚举 FOR /F“delims=...”命令中的项目。
您只需要在字符串中插入一些换行符即可。

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"
)

There IS a way to directly enumerate items in a FOR /F "delims=..." command.
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"
)
泪眸﹌ 2025-01-10 17:59:15

Aacini 建议使用简单的 FOR 而不是 FOR /F 是一个很好的解决方案,除非字符串可能包含通配符 *??字符可以通过搜索和替换来保护,但是没有有效的方法来批量替换*

如果遇到通配符问题,则可以恢复为在循环中使用 FOR /F 一次解析一个单词。大多数人使用 GOTO 来完成循环,因为您无法知道会找到多少个单词。但GOTO比较慢。通过对任意数量的项目使用外部 FOR 循环(不是 FOR /L),您可以显着提高性能。在正文中,只要没有更多单词,您就可以使用 GOTO 退出循环。如果循环失败而没有耗尽单词,则可以使用 GOTO 重新启动循环。具有 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

与所有 FOR 循环一样,如果在扩展 %%A 变量时启用延迟扩展,则必须担心 !^ 的损坏。

FOR /L 不应该用于外循环,因为 FOR /L 总是完成所有迭代的计数,即使您在主体内使用 GOTO 也是如此。

Aacini's suggestion to use a simple FOR instead of FOR /F is a good solution, unless the string might contain wildcard characters * or ?. 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. Most people use GOTO to accomplish the loop because you have no way of knowing how many words you will find. But GOTO is relatively slow. You can achieve a significant performance boost by using an outer FOR loop (not FOR /L) with an arbitrarily large number of items. Within the body you can exit the loop with a GOTO whenever there are no more words. If the loop falls through without exhausting the words, you can use a GOTO to restart the loop. An outer loop with 100 items will only perform 1 GOTO per 100 parsed words.

@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 ! and ^ if delayed expansion is enabled when the %%A variable is expanded.

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文