web-dev-qa-db-fra.com

Comment pouvez-vous parcourir chaque ligne d'un fichier texte à l'aide d'un fichier de commandes Windows?

J'aimerais savoir comment parcourir chaque ligne d'un fichier texte à l'aide d'un fichier de commandes Windows et traiter chaque ligne de texte successivement.

207
Mr. Kraus

Les messages ci-dessous ont beaucoup aidé, mais n'ont pas fait ce que j'avais indiqué dans ma question, à savoir que je devais traiter la totalité de la ligne. Voici ce que j'ai trouvé pour travailler.

for /F "tokens=*" %%A in (myfile.txt) do [process] %%A

Le mot-clé tokens avec un astérisque (*) extraira tout le texte de la ligne entière. Si vous ne mettez pas d’astérisque, il ne fera que tirer le premier mot en ligne. Je suppose que cela a à voir avec les espaces. 

Pour commander sur TechNet

J'apprécie tous les messages!


S'il y a des espaces dans votre chemin de fichier, vous devez utiliser usebackq. Par exemple.

for /F "usebackq tokens=*" %%A in ("my file.txt") do [process] %%A
270
Mr. Kraus

A partir de la référence de ligne de commande Windows:

Pour analyser un fichier en ignorant les lignes commentées, tapez:

for /F "eol=; tokens=2,3* delims=," %i in (myfile.txt) do @echo %i %j %k

Cette commande analyse chaque ligne de Myfile.txt en ignorant les lignes commençant par un point-virgule et en transmettant les deuxième et troisième jetons de chaque ligne au corps FOR (les jetons sont délimités par des virgules ou des espaces). Le corps de l'instruction FOR fait référence à% i pour obtenir le deuxième jeton, à% j pour obtenir le troisième jeton et à% k pour obtenir tous les jetons restants. 

Si les noms de fichier que vous fournissez contiennent des espaces, utilisez des guillemets autour du texte (par exemple, "Nom du fichier"). Pour utiliser des guillemets, vous devez utiliser usebackq. Sinon, les guillemets sont interprétés comme définissant une chaîne littérale à analyser.

En passant, vous pouvez trouver le fichier d’aide en ligne de commande sur la plupart des systèmes Windows à l’adresse:

 "C:\WINDOWS\Help\ntcmds.chm"
53
Ash

Dans un fichier de lot, vousDEVEZutiliser %% au lieu de %: (Tapez help for)

for /F "tokens=1,2,3" %%i in (myfile.txt) do call :process %%i %%j %%k
goto thenextstep
:process
set VAR1=%1
set VAR2=%2
set VAR3=%3
COMMANDS TO PROCESS INFORMATION
goto :EOF

Ce que cela fait: L’appel "do: process %% i %% j %% k" à la fin de la commande for transmet les informations acquises dans la commande for de myfile.txt au "processus" 'sous-programme' .

Lorsque vous utilisez la commande for dans un programme de traitement par lots, vous devez utiliser le double signe% pour les variables.

Les lignes suivantes transmettent ces variables de la commande for à la «sous-routine» du processus et vous permettent de traiter ces informations.

set VAR1=%1
 set VAR2=%2
 set VAR3=%3

J'ai quelques utilisations assez avancées de cette configuration exacte que je serais prêt à partager si d'autres exemples sont nécessaires. Ajoutez votre EOL ou Delims au besoin bien sûr.

30
user332474

Amélioration de la première réponse "FOR/F ..": Ce que je devais faire était d'appeler exécuter tous les scripts répertoriés dans MyList.txt, cela a donc fonctionné pour moi:

for /F "tokens=*" %A in  (MyList.txt) do CALL %A ARG1

--OU, si vous souhaitez le faire sur plusieurs lignes: 

for /F "tokens=*" %A in  (MuList.txt) do (
ECHO Processing %A....
CALL %A ARG1
)

Edit: L’exemple ci-dessus concerne l’exécution de la boucle FOR à partir d’une invite de commande; à partir d'un script batch, un% supplémentaire doit être ajouté, comme indiqué ci-dessous:

---START of MyScript.bat---
@echo off
for /F "tokens=*" %%A in  ( MyList.TXT) do  (
   ECHO Processing %%A.... 
   CALL %%A ARG1 
)
@echo on
;---END of MyScript.bat---
22
Yogesh Mahajan

@/MrKraus réponse est instructif. De plus, laissez-moi ajouter que si vous souhaitez charger un fichier situé dans le même répertoire que le fichier de traitement par lots, préfixez le nom du fichier avec% ~ dp0. Voici un exemple:

cd /d %~dp0
for /F "tokens=*" %%A in (myfile.txt) do [process] %%A

NB:: Si votre nom de fichier ou votre répertoire (par exemple, monfichier.txt dans l'exemple ci-dessus) comporte un espace (par exemple, 'mon fichier.txt' ou 'c:\Program Files'), utilisez:

for /F "tokens=*" %%A in ('type "my file.txt"') do [process] %%A

, avec le mot clé type appelant le programme type, qui affiche le contenu d’un fichier texte. Si vous ne voulez pas subir la surcharge de l'appel de la commande type, vous devez changer le répertoire en répertoire du fichier texte. Notez que ce type est toujours requis pour les noms de fichier avec des espaces.

J'espère que ça aidera quelqu'un!

21
Marvin Thobejane

La réponse acceptée est bonne, mais présente deux limites.
Il supprime les lignes vides et les lignes commençant par ;

Pour lire les lignes de tout contenu, vous avez besoin de la technique de basculement par expansion retardée. 

@echo off
SETLOCAL DisableDelayedExpansion
FOR /F "usebackq delims=" %%a in (`"findstr /n ^^ text.txt"`) do (
    set "var=%%a"
    SETLOCAL EnableDelayedExpansion
    set "var=!var:*:=!"
    echo(!var!
    ENDLOCAL
)

Findstr est utilisé pour préfixer chaque ligne du numéro et des deux-points, les lignes vides ne sont donc plus vides. 

DelayedExpansion doit être désactivé lors de l'accès au paramètre %%a; sinon, les points d'exclamation ! et carets ^ seront perdus car ils ont une signification particulière dans ce mode. 

Toutefois, pour supprimer le numéro de ligne de la ligne, l’extension différée doit être activée.
set "var=!var:*:=!" supprime tout jusqu'au premier deux-points (utiliser delims=: enlèverait également tous les deux-points au début d'une ligne, pas seulement celui de findstr).
Le local final désactive à nouveau l’extension différée pour la ligne suivante.

La seule limite est maintenant la limite de longueur de ligne d'environ 8191, mais il ne semble pas y avoir de moyen de la surmonter. 

14
jeb

Ou, vous pouvez exclure les options entre guillemets:

FOR /F %%i IN (myfile.txt) DO ECHO %%i
13
Paul

Voici un fichier bat que j'ai écrit pour exécuter tous les scripts SQL d'un dossier:

REM ******************************************************************
REM Runs all *.sql scripts sorted by filename in the current folder.
REM To use integrated auth change -U <user> -P <password> to -E
REM ******************************************************************

dir /B /O:n *.sql > RunSqlScripts.tmp
for /F %%A in (RunSqlScripts.tmp) do osql -S (local) -d DEFAULT_DATABASE_NAME -U USERNAME_GOES_HERE -P PASSWORD_GOES_HERE -i %%A
del RunSqlScripts.tmp
9
mikej

Si vous avez une famille Windows NT (une avec cmd.exe comme shell), essayez la commande FOR/F .

5

Exemples modifiés ici pour lister nos applications Rails sur Heroku - merci!

cmd /C "heroku list > heroku_apps.txt"
find /v "=" heroku_apps.txt | find /v ".TXT" | findstr /r /v /c:"^$" > heroku_apps_list.txt
for /F "tokens=1" %%i in (heroku_apps_list.txt) do heroku run bundle show Rails --app %%i

Code complet ici .

1
sendbits

La réponse acceptée en utilisant cmd.exe et 

for /F "tokens=*" %F in (file.txt) do whatever "%F" ...

ne fonctionne que pour les fichiers "normaux". Il échoue lamentablement avec d'énormes fichiers.

Pour les gros fichiers, vous devrez peut-être utiliser Powershell et quelque chose comme ceci:

[IO.File]::ReadLines("file.txt") | ForEach-Object { whatever "$_" }

ou si vous avez assez de mémoire:

foreach($line in [System.IO.File]::ReadLines("file.txt")) { whatever "$line" } 

Cela a fonctionné pour moi avec un fichier de 250 Mo contenant plus de 2 millions de lignes, où la commande for /F ... s'est bloquée après quelques milliers de lignes.

Pour connaître les différences entre foreach et ForEach-Object, voir Apprendre à connaître ForEach et ForEach-Object .

(crédits: Lisez le fichier ligne par ligne dans PowerShell )

0
mivk