Как прокручивать токены в строке?

Скажем, у меня есть строка, такая как foo: bar: baz, можно ли пропустить эту строку? Похоже, что вы можете маркировать строки файла, но следующее будет только эхо "foo" один раз.

for /f "tokens=1,2* delims=:" %%x in ("%%j") do echo %%x

Ответ 1

set string=foo:bar:baz
for %%x in (%string::= %) do echo %%x

Для разделителей значений FOR могут быть пробелы, запятые, точки с запятой и знак равенства. Вы можете напрямую обрабатывать строку, если элементы разделены с любым из этих символов. Если нет, просто измените разделитель на один из этих символов (как я уже говорил выше).

set string=foo bar,baz;one=two
for %%x in (%string%) do echo %%x

Ответ 2

Аасини избил меня до своего первого решения. Его можно улучшить, добавив кавычки, чтобы строка могла содержать пробелы и специальные символы и при этом давать правильный результат.

set "str=foo bar:biz bang:this & that"
for %%S in ("%str::=" "%") do echo %%~S

Решение имеет ограничения:

  • Нет * или? может появиться в строке
  • Проблемы могут возникнуть, если строка уже содержит кавычки ("), особенно если есть специальные символы.

Второе решение имеет странный синтаксис, но концепция довольно прямолинейна. FOR/F с "string" будет разбиваться на символы перевода строки - каждая строка будет обрабатываться как собственная строка. Трюк заключается в замене разделителя : символом перевода строки. Обратите внимание, что пустая строка в приведенном ниже решении является важной частью сложной замены. Кроме того, следующая строка должна начинаться с !, которая завершает расширение с задержкой. Не должно быть никаких ведущих пробелов.

Другая вещь, о которой стоит беспокоиться, - это досадный FOR/F "EOL" вариант. Мы не хотим пропускать любые значения, начинающиеся с символа EOL, который по умолчанию равен ;. Поскольку мы исключили разделитель строк :, мы можем безопасно использовать это как EOL.

Наконец, нам нужно использовать задержанное расширение, но ! будет повреждено во время расширения %% S, если мы не будем сначала отключать замедленное расширение в цикле.

set "str=foo bar:biz bang:this & that "^& the other thing!":;How does this work?"
setlocal enableDelayedExpansion
set ^"str=!str::=^

!"
for /f "eol=: delims=" %%S in ("!str!") do (
  if "!!"=="" endlocal
  echo %%S
)

Я считаю, что эта техника может справиться практически со всем, что вы бросаете на нее.

jeb был первым, кто показал мне, как работать с линейными каналами внутри партии, и особенно, как использовать эту технику. Он может даже быть размещен уже где-то в SO.

Ответ 3

он делает так, как ожидалось, он токенизирует его до %%x %%y %%z. Поэтому вместо обработки %%x вы можете...

for /f "tokens=* delims=:" %%x in ("foo:bar:baz") do (
  echo %%x
  echo %%y
  echo %%z
)

или если вы не знаете заранее, сколько у вас предметов, вы можете...

@echo off
set string=foo:bar:baz
:again
for /f "tokens=1* delims=:" %%x in ("%string%") do (
   echo %%x 
   set string=%%y
)
if not .%string%==. goto again
echo done

Ответ 4

Это проанализирует строку в переменных, доступных вне цикла (;

setlocal enabledelayedexpansion

set your_string="whatever:you:want"

for /f "tokens=1,2,3 delims=:" %%a in ('echo !your_string!') do (
    set first_sub_string=%%a
    set second_sub_string=%%b
    set third_sub_string=%%c
)

echo Congrats.  !your_string! was parsed as !first_sub_string!, !second_sub_string!, !third_sub_string!