2011-12-13 17 views
14

Digamos que tengo una cadena como foo: bar: baz, ¿es posible recorrer esta cadena? Parecía que se podían tokenizar líneas de un archivo, pero lo siguiente solo haría eco de 'foo' una vez.¿Cómo se repiten los tokens en una cadena?

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

Respuesta

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

PARA Los delimitadores de valores pueden ser espacio, coma, punto y coma e igual-signo. Puede procesar directamente una cadena si los elementos están delimitados con cualquiera de estos caracteres. Si no, simplemente cambie el delimitador para uno de estos caracteres (como hice anteriormente).

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

+1 mucho más fácil! –

2

sí como se espera, tokenizes a %%x%%y%%z. Así que en lugar de sólo el procesamiento de %%x, es posible que ...

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

o si no saber de antemano cuántos artículos que usted consiguió, es posible que ...

@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 
+0

hmm, creo que lo que quiero es ser capaz de bucle a través de fichas como que puede recorrer líneas en un archivo Un Una buena manera de hacer esto: http://stackoverflow.com/questions/6966558/batch-file-for-f-tokens –

8

Aacini me ganó a mi primera solución. Se puede mejorar agregando comillas para que la cadena pueda contener espacios y caracteres especiales y aun así dar el resultado correcto.

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

La solución tiene limitaciones:

  • n * o? puede aparecer en la cadena
  • Los problemas pueden surgir si la cadena ya contiene comillas ("), sobre todo si hay caracteres especiales, así

La segunda solución tiene una sintaxis extraña, pero el concepto es bastante sencillo. FOR/F con "cadena" se romperá en los caracteres de avance de línea - cada línea se procesará como su propia cadena. El truco es reemplazar el delimitador : con un carácter de avance de línea. Tenga en cuenta que la línea en blanco en la solución a continuación es una parte crítica de El reemplazo complicado. Además, la siguiente línea debe comenzar con el ! que finaliza la expansión de la variable retrasada. No debe haber espacios iniciales.

La otra cosa de la que preocuparse es la molesta opción FOR/F "EOL". No queremos omitir ningún valor que comience por defecto con el carácter EOL que es ;. Como hemos eliminado el delimitador de cadena :, podemos usarlo como EOL.

Finalmente, necesitamos usar la expansión retardada, pero ! se dañará durante la expansión %% S si no deshabilitamos primero la expansión retardada dentro del ciclo.

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 
) 

Creo que esta técnica puede manejar casi cualquier cosa que le arroje.

jeb fue el primero en mostrarme cómo trabajar con las alimentaciones de línea en lote, y especialmente cómo usar esta técnica. Incluso puede publicarse en otro lugar en SO.

+0

¿Puede decirme por qué está escapando la primera comilla como '^" 'en el reemplazo de cuerdas? y por qué no escapas el segundo? – aschipfl

+0

¡Ah, maldición, soy estúpido! Lo sé: un' 'no guardado '' haría que el'^'se mantuviera literalmente ... extrañamente encontré que no probando el código sino atendiendo algo co completamente diferente desde que publiqué el comentario; bastante nerd, ¿no es así? ;-) – aschipfl

1

Esto analizar la cadena en variables accesible fuera del bucle (;.

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! 
Cuestiones relacionadas