Pregunta

He estado programando en docenas de idiomas durante 20 años, pero nunca pude entender cómo " PARA " trabaje en el archivo por lotes de shell de cmd de Windows, no importa cuánto lo intenté Yo leo

http://www.amazon.com/Windows-Administration-Command-Line- Vista / dp / 0470046163 / ref = sr_1_1? Ie = UTF8 & amp; s = libros & amp; qid = 1241362727 & amp; sr = 8-1

http://www.ss64.com/nt/for.html

y varios otros artículos en Internet, pero aún así se confunden y no pueden lograr nada.

¿Alguien me puede dar una explicación concisa sobre cómo " PARA " funciona en general?

Para una pregunta un poco más específica, ¿cómo puedo recorrer cada ruta en la variable% PATH%? Lo he intentado con

rem showpathenv.bat
for /f "delims=;" %%g in ("%PATH%") do echo %%g

Eso solo mostraría el primer camino, no todos. Por qué ? ¿Qué hago mal?

¿Fue útil?

Solución

Ninguna de las respuestas realmente funciona. He logrado encontrar la solución yo mismo. Esto es un poco pirateado, pero me soluciona el problema:

echo off
setlocal enableextensions
setlocal enabledelayedexpansion
set MAX_TRIES=100
set P=%PATH%
for /L %%a in (1, 1, %MAX_TRIES%) do (
  for /F "delims=;" %%g in ("!P!") do (
    echo %%g
    set P=!P:%%g;=!
    if "!P!" == "%%g" goto :eof
  )
)

¡Oh! ¡Odio la programación de archivos por lotes!

Actualizado

La solución de Mark es más simple pero no funcionará con una ruta que contenga espacios en blanco. Esta es una versión poco modificada de la solución de Mark

echo off
setlocal enabledelayedexpansion
set NonBlankPath=%PATH: =#%
set TabbedPath=%NonBlankPath:;= %
for %%g in (%TabbedPath%) do (
  set GG=%%g
  echo !GG:#= !
)

Otros consejos

La idea de Mark fue buena, pero tal vez se olvidó que algún camino tiene espacios en ellos. Sustitución de ';' con '" " ' en su lugar, cortaría todos los caminos en cadenas entre comillas.

set _path="%PATH:;=" "%"
for %%p in (%_path%) do if not "%%~p"=="" echo %%~p

Aquí, tienes tus rutas mostradas.

El comando FOR en cmd tiene una curva de aprendizaje tediosa, especialmente porque la forma en que reaccionan las variables dentro de las declaraciones de () ... puede asignar cualquier variable, pero no puede volver a leer dentro de los (), a menos que utilice la opción " setlocal ENABLEDELAYEDEXPANSION " y, por lo tanto, también use las variables con! 's en lugar de las de %% (! _var!)

Actualmente, solo guión con cmd, para el trabajo, tuve que aprender todo esto :)

Tienes la idea correcta, pero for / f está diseñado para funcionar en comandos o archivos de varias líneas, no en cadenas individuales.

En su forma más simple, for es como el for de Perl, o foreach de todos los demás idiomas. Le pasas una lista de tokens, e itera sobre ellos, llamando al mismo comando cada vez.

for %a in (hello world) do @echo %a

Las extensiones simplemente proporcionan formas automáticas de crear la lista de tokens. La razón por la que su código actual no aparece es que '; ' es el símbolo predeterminado de final de línea (comentario). Pero incluso si cambias eso, deberías usar %% g, %% h, %% i, ... para acceder a los tokens individuales, lo que limitará gravemente tu archivo por lotes.

Lo más cerca que puede llegar a lo que pide es:

set TabbedPath=%PATH:;= %
for %%g in (%TabbedPath%) do echo %%g

Pero eso fallará para las rutas citadas que contienen puntos y comas.

En mi experiencia, for / l y for / r son buenos para extender los comandos existentes, pero por lo demás for es extremadamente limitado. Puede hacerlo un poco más poderoso (y confuso) con la expansión variable retrasada ( cmd / v: on ), pero en realidad solo es bueno para las listas de nombres de archivos.

Le sugeriría usar WSH o PowerShell si necesita realizar una manipulación de cadenas. Si intentas escribir whereis para Windows, prueba where /? .

No pude resistirme a lanzar esto por ahí, ya que este hilo es ... Por lo general, cuando surge la necesidad de recorrer cada uno de los archivos de PATH, todo lo que realmente desea hacer es encontrar un archivo en particular ... Si ese es el caso, esta sola línea escupirá el primer directorio en el que encuentre su archivo:

(ej: buscando java.exe)

for %%x in (java.exe) do echo %%~dp$PATH:x

Sé que esto es SUPERTO viejo ... pero solo por diversión decidí intentarlo:

@Echo OFF
setlocal
set testpath=%path: =#%
FOR /F "tokens=* delims=;" %%P in ("%testpath%") do call :loop %%P
:loop
if '%1'=='' goto endloop
set testpath=%1
set testpath=%testpath:#= %
echo %testpath%
SHIFT
goto :loop
:endloop
pause
endlocal
exit

Esto no requiere un conteo y continuará hasta que termine. Tuve el mismo problema con los espacios pero lo hizo a través de toda la variable. La clave para esto son las etiquetas de bucle y la función SHIFT .

para / f itera por entrada de línea, por lo que en su programa solo se mostrará la primera ruta.

su programa trata a% PATH% como una entrada de una línea, y elimina por ; , ponga el primer resultado en %% g, luego la salida %% g (primera ruta eliminada).

FOR está básicamente iterando sobre las " líneas " en el conjunto de datos. En este caso, hay una línea que contiene la ruta. El " delims =; " solo le dice que se separe en punto y coma. Si cambia el cuerpo a echo %% g, %% h, %% i, %% j, %% k verá que trata la entrada como una sola línea y la rompe en múltiples fichas.

Esto funciona para mí:

@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION ENABLEEXTENSIONS
@REM insure path is terminated with a ;
set tpath=%path%;
echo.
:again
@REM This FOR statement grabs the first element in the path
FOR /F "delims=;" %%I IN ("%TPATH%") DO (
  echo    %%I 
  @REM remove the current element of the path
  set TPATH=!TPATH:%%I;=!
)
@REM loop back if there is more to do. 
IF DEFINED TPATH GOTO :again

ENDLOCAL

También tiene que usar la parte tokens = 1,2, ... de las opciones que permite el bucle for . Esto aquí hará lo que posiblemente quieras:

for /f "tokens=1,2,3,4,5,6,7,8,9,10,11,12 delims=;" %a in ("%PATH%") ^
do ( ^
     echo. %b ^
   & echo. %a ^
   & echo. %c ^
   & echo. %d ^
   & echo. %e ^
   & echo. %f ^
   & echo. %g ^
   & echo. %h ^
   & echo. %i ^
   & echo. %j ^
   & echo. %k ^
   & echo. ^
   & echo.   ...and now for some more... ^
   & echo. ^
   & echo. %a ^| %b ___ %c ... %d ^
   & dir "%e" ^
   & cd "%f" ^
   & dir /tw "%g" ^
   & echo. "%h  %i  %j  %k" ^
   & cacls "%f")

Este ejemplo procesa los primeros 12 tokens (= directorios de% path%) solamente. Utiliza la enumeración explícita de cada uno de los tokens utilizados. Tenga en cuenta que los nombres de token distinguen entre mayúsculas y minúsculas:% a es diferente de% A.

Para guardar las rutas con espacios, rodee all % x con comillas como esta "% i " ;. No lo hice aquí donde solo estoy haciendo eco de los tokens.

También podría hacer en el s.th. de esta manera:

for /f "tokens=1,3,5,7-26* delims=;" %a in ("%PATH%") ^
do ( ^
     echo. %c ^
   & echo. %b ^
   & echo. %a ^
   & echo. %d ^
   & echo. %e ^
   & echo. %f ^
   & echo. %g ^
   & echo. %h ^
   & echo. %i ^
   & echo. %j ^
   & echo. %k )

Éste omite tokens 2,4,6 y usa un pequeño atajo (" 7-26 ") para nombrar el resto de ellos. Observe cómo% c,% b,% a se procesan en orden inverso esta vez y cómo ahora "significan" diferentes tokens, en comparación con el primer ejemplo.

Entonces, esta seguramente no es la explicación concisa que pediste. Pero tal vez los ejemplos ayuden a aclarar un poco mejor ahora ...

Aquí hay una buena guía:

FOR / F - Comando de bucle: contra un conjunto de archivos.

FOR / F - Comando de bucle: contra los resultados de otro comando.

FOR - Comando de bucle: todas las opciones Archivos, Directorio, Lista.

[Toda la guía (comandos de Windows XP):

http://www.ss64.com/nt/index.html

Editar: Lo sentimos, no vi que el enlace ya estuviera en el OP, ya que me parecía que formaba parte del enlace de Amazon.

Funciona para mí, pruébalo.

for /f "delims=;" %g in ('echo %PATH%') do echo %g%

Funciona para mí, pruébalo.

para / f " tokens = * delims =; " % g en ('echo% PATH%') haz echo% g%

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top