Domanda

Sto programmando in dozzine di lingue da 20 anni ma non sono mai riuscito a capire come " PER " lavorare nel file batch shell cmd di Windows, non importa quanto ci abbia provato. Ho letto

http://www.amazon.com/Windows-Administration-Command-Line- Vista / dp / 0470046163 / ref = sr_1_1 ie = UTF8 & amp;? s = libri & amp; qid = 1.241.362,727 mila & amp; sr = 8-1

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

e molti altri articoli su Internet ma continuano a confondere e non riescono a realizzare nulla.

Qualcuno può darmi una spiegazione concisa su come " PER " funziona in generale?

Per una domanda un po 'più specifica, come posso scorrere ogni percorso nella variabile% PATH%? Ho provato con

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

Questo mostrerebbe solo il primo percorso, non tutti. Perché ? Cosa faccio di sbagliato?

È stato utile?

Soluzione

Nessuna delle risposte funziona davvero. Sono riuscito a trovare la soluzione da solo. Questo è un po 'hacker, ma risolve il problema per me:

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 programmazione di file batch !!

Aggiornamento

La soluzione di Mark è più semplice ma non funzionerà con il percorso contenente spazi bianchi. Questa è una versione leggermente modificata della soluzione di Mark

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

Altri suggerimenti

L'idea di Mark era buona, ma forse ho dimenticato che alcuni percorsi hanno degli spazi. Sostituzione di ';' con "" & Quot;' invece taglierebbe tutti i percorsi in stringhe tra virgolette.

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

Quindi, qui hai i tuoi percorsi visualizzati.

Il comando FOR in cmd ha una noiosa curva di apprendimento, in particolare perché il modo in cui le variabili reagiscono all'interno delle istruzioni di () ... puoi assegnare qualsiasi variabile, ma non puoi rileggere all'interno di () a meno che tu non utilizzare il "setlocal ENABLEDELAYEDEXPANSION" e quindi usa anche le variabili con !! 's anziché %%' s (! _var!)

Al momento ho scritto esclusivamente script con cmd, per lavoro, ho dovuto imparare tutto questo :)

Hai l'idea giusta, ma for / f è progettato per funzionare su file o comandi multilinea, non su singole stringhe.

Nella sua forma più semplice, per è come il per di Perl, o il foreach di ogni altra lingua. Gli passi un elenco di token e scorre su di essi, chiamando ogni volta lo stesso comando.

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

Le estensioni forniscono semplicemente modi automatici di costruire l'elenco di token. Il motivo per cui il tuo codice attuale non presenta nulla è che "; 'è il simbolo di fine riga predefinito (commento). Ma anche se lo cambi, dovresti usare %% g, %% h, %% i, ... per accedere ai singoli token, il che limiterà notevolmente il tuo file batch.

Il più vicino che puoi ottenere a ciò che chiedi è:

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

Ma ciò fallirà per i percorsi tra virgolette che contengono punti e virgola.

Nella mia esperienza, for / l e for / r sono buoni per estendere i comandi esistenti, ma altrimenti per è estremamente limitato. Puoi renderlo leggermente più potente (e confuso) con l'espansione variabile ritardata ( cmd / v: on ), ma è davvero buono solo per elenchi di nomi di file.

Suggerirei di utilizzare WSH o PowerShell se è necessario eseguire la manipolazione delle stringhe. Se stai cercando di scrivere whereis per Windows, prova where /? .

Non ho potuto resistere a lanciarlo là fuori, vecchio come questo thread è ... Di solito quando sorge la necessità di scorrere attraverso ciascuno dei file in PATH, tutto ciò che vuoi davvero fare è trovare un file particolare ... Se questo è il caso, questo one-liner sputerà la prima directory in cui trova il tuo file:

(ad esempio: cercando java.exe)

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

So che è SUPER vecchio ... ma solo per divertimento ho deciso di provarlo:

@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

Questo non richiede un conteggio e andrà fino al termine. Ho avuto lo stesso problema con gli spazi ma è riuscito a superare l'intera variabile. La chiave di ciò sono le etichette del ciclo e la funzione SHIFT .

per / f scorre per input di riga, quindi nel tuo programma verrà emesso solo il primo percorso.

il tuo programma considera% PATH% come input di una riga e delimita da ; , inserisci il primo risultato in %% g, quindi genera %% g (primo percorso delimitato).

FOR sta essenzialmente iterando sulle "righe" nel set di dati. In questo caso, esiste una riga che contiene il percorso. Il " delims =; " gli sta semplicemente dicendo di separarsi sui punti e virgola. Se cambi il corpo in echo %% g, %% h, %% i, %% j, %% k noterai che sta trattando l'input come una singola riga e spezzandolo in più token.

Questo funziona per me:

@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

Devi inoltre utilizzare la parte tokens = 1,2, ... delle opzioni consentite dal ciclo per . Questo qui farà ciò che desideri:

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

Questo esempio elabora solo i primi 12 token (= directory da% path%). Utilizza l'enumerazione esplicita di ciascuno dei token utilizzati. Nota che i nomi dei token fanno distinzione tra maiuscole e minuscole:% a è diverso da% A.

Per salvare i percorsi con spazi, racchiudi tutti % x con virgolette come questa "% i " ;. Non l'ho fatto qui dove sto solo facendo eco ai token.

Potresti anche fare la s.th. in questo modo:

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 )

Questo salta i token 2,4,6 e usa una scorciatoia (" 7-26 ") per nominarne il resto. Nota come% c,% b,% a vengono elaborati in ordine inverso questa volta e come ora "significano" token diversi, rispetto al primo esempio.

Quindi questa sicuramente non è la spiegazione concisa che hai chiesto. Ma forse gli esempi aiutano a chiarire un po 'meglio ora ...

Ecco una buona guida:

FOR / F - Comando loop: contro un set di file.

FOR / F - Comando loop: contro i risultati di un altro comando.

FOR - Comando Loop: tutte le opzioni File, Directory, Elenco.

[Tutta la guida (comandi di Windows XP):

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

Modifica: Spiacenti, non ho visto che il collegamento era già nell'OP, poiché mi è apparso come parte del collegamento Amazon.

Funziona per me, provalo.

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

Funziona per me, provalo.

per / f " tokens = * delims =; " % g in ('echo% PATH%') fa l'eco% g%

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top