Lire une variable contenu dans un fichier durant une boucle ?

Lire une variable contenu dans un fichier durant une boucle ? - Shell/Batch - Programmation

Marsh Posté le 27-04-2015 à 17:18:51    

Salut à tous,
 
une question toute bête mais je n'ai pas trouvé ma réponse.
 
Je cherche à exécuter une commande via une boucle dans un fichier batch.La particularité est que le fichier appelé dans ma boucle peut contenir un chemin défini par un path. Or via mon script, le path n'est pas interprété.
 
Voici un exemple de script :  
 

Code :
  1. @echo on
  2. for /f "tokens=* delims= " %%b in (FilePath.txt) do (
  3. REM echo "le nom du fichier est %%b"
  4. )
  5. @pause


 
Et dans mon fichier FilePath.txt, j'ai  
%windir%\moi.txt
C:\WINDOWS\system32\test.txt

La ligne "%windir%\moi.txt" n'est pas traduite en C:\WINDOWS\moi.txt et par conséquent ca ne fonctionne pas.

 
Qu'est ce que j'oublie ?  
 
Merci
 
 
 

Reply

Marsh Posté le 27-04-2015 à 17:18:51   

Reply

Marsh Posté le 27-04-2015 à 19:10:46    

Eh ben... Je tire mon chapeau devant les gens qui savent utiliser cette cochonnerie de batch! :cry:  
 
Pour le problème le seul truc qui fonctionne chez moi c'est mettre le traitement dans une fonction qu'on appelle:

Code :
  1. @echo off
  2. for /f "tokens=* delims= " %%b in (FilePath.txt) do call :process %%b
  3. goto :eof
  4. :process
  5. echo %1


selon http://stackoverflow.com/questions [...] n-for-loop  
 
Apparemment c'est un truc avec ENABLEDELAYEDEXPANSION mais j'ai pas réussi à faire fonctionner, peut-être qu'à l'intérieur d'une boucle ça ne marche pas??

Reply

Marsh Posté le 29-04-2015 à 17:47:15    

Hello,
 
merci pour ta réponse; j'ai utilisé ta méthode mais je rencontre du coup un autre problème.
 
Le "ErrorLevel" retourné par ma commande FINDSTR est toujours égal à 1 et jamais à 0 (chaine de caractère trouvée).
 
Voilà un bout de mon code si quelqu'un à une idée; je sèche pour l'instant

Code :
  1. for /f "tokens=* delims= " %%b in (FileItemWithPath.txt) do call :process %%b
  2. goto :eof
  3. :process
  4. echo %1
  5. findstr %1 D:\Dir_CD.txt
  6. echo L errorlevel est de : !ERRORLEVEL!pour le fichier %1
  7. If !ERRORLEVEL! EQU 0 (
  8. findstr %1 D:\Dir_CD.txt >> %computername%_File.csv
  9. REM echo "Fichier %%a est present sur %computername%" >> %computername%_reg.csv


 
Merci

Reply

Marsh Posté le 29-04-2015 à 21:53:38    

Je suis pas sûr de comprendre ce que tu veux faire... findstr sert à chercher des choses à l'intérieur d'un fichier, c'est bien ça que tu veux ou plutôt comparer des chaînes de caractères? (je pense à la ligne findstr %1 D:\Dir_CD.txt)

Reply

Marsh Posté le 29-04-2015 à 22:38:46    

Je veux chercher si une chaine de caractères qui est présente dans le fichier "FileItemWithPath.txt" est également présente dans le fichier DIR_CD.txt
 
 
En gros le fichier "DIC_CD.txt", contient un dir de tous mon disque dur avec donc le nom de chaque fichier de mon disque ligne par ligne.
Le fichier "FileItemWithPath.txt" contient des noms de fichiers (sous la forme c:\chemin\fichier.txt).
 
Le but de la boucle est de chercher dans DIR_CD si chaque ligne de "FileItemWithPath" est présente.
 
Merci pour tes lumières :D
 

Reply

Marsh Posté le 29-04-2015 à 23:07:10    

Citation :

Le "ErrorLevel" retourné par ma commande FINDSTR est toujours égal à 1 et jamais à 0 (chaine de caractère trouvée).


C'est apparemment un problème avec les backslash...
 
Ceci fonctionne:
Dans un même dossier:
test.bat

Code :
  1. @echo off
  2. for /f "tokens=* delims= " %%b in (FileItemWithPath.txt) do call :process %%b
  3. goto :eof
  4. :process
  5. findstr %1 D:\Dir_CD.txt >NUL
  6. echo errorlevel est de : %ERRORLEVEL% pour le fichier %1


et FileItemWithPath.txt

Code :
  1. abc123
  2. c:dossierfichier.txt


 
Sur D:\
Dir_CD.txt

Code :
  1. c:dossierfichier.txt


 
Si je remets les '\' ou '\\', autrement dit si je change c:dossierfichier.txt en c:\dossier\fichier.txt ou c:\\dossier\\fichier.txt dans les deux fichiers ça ne fonctionne plus... Je sais pas pourquoi.
 
Mais dis, tu es obligé de te servir de batch? Parce que avec un language correct (p.ex. Perl) ça serait bien plus facile!!

Reply

Marsh Posté le 29-04-2015 à 23:13:25    

Ok, si il y a que des '\' (et non des doubles '\\') faut mettre /L en paramètre à findstr et ça semble fonctionner.

Reply

Marsh Posté le 30-04-2015 à 10:07:50    

Merci pour ta réponse mais j'ai apparemment toujours le même problème même avec le /L à mon findstr si je l'insère dans un batch et qu"une variable d'environnement est traduite.
 
En gros,  

  • Je n'ai pas de résultat si je lance depuis une cmd la commande suivante :  
Code :
  1. findstr c:\Windows\System32\test.dll  d:\DIr_cd.txt


 

  • J'ai un résultat si je lance depuis une cmd la commande suivante :  
Code :
  1. findstr /L c:\Windows\System32\test.dll  d:\DIr_cd.txt


 
Cependant dans mon .bat, j'ai toujours un ERRORLEVEL à 1 même avec le "/L" :  
 

Code :
  1. for /f "tokens=* delims= " %%b in (FileItemWithPath.txt) do call :process %%b
  2. goto :eof
  3. :process
  4. echo %1
  5. findstr /L %1 D:\Dir_CD.txt
  6. echo L errorlevel est de : %ERRORLEVEL% pour le fichier %1
  7. If %ERRORLEVEL% EQU 0 (
  8. findstr /L %1 D:\Dir_CD.txt >> %computername%_File.csv
  9. REM echo "Fichier %%a est present sur %computername%" >> %computername%_reg.csv
  10.     )
  11. @pause


 
Si dans mon fichier FileItemWithPath.txt, j'ai c:\windows\test.dll ca fonctionne.
Si par contre j'ai %systemroot%\test.dll ca ne fonctionne pas (bien que l'echo me montre bien que le chemin "traduit" est fourni à findstr (donc c:\windows).
 
 
Voilà, si tu as une idée je suis preneur. (et pour répondre à une de tes idées, je ne peux donc malheureusement pas supprimer les "\" de mon fichier "FileItemWithPath" car le fichier contient des variables d'environnement (par ex %sytemroot%) qui inclut des "\" par défaut.
 
=)

Reply

Marsh Posté le 30-04-2015 à 11:33:42    

Apparemment c'est un problème lié à la casse.
 
Suivant que les lettres sont en majuscules ou minuscules ca marche ou pas ... On a moyen de jouer sur la casse dans un batch ?

Reply

Marsh Posté le 30-04-2015 à 12:59:31    

RTFM  :)  
 
findstr /? pour avoir l'aide
 
findstr /I (i majuscule) pour ignorer la casse (non testé)

Reply

Marsh Posté le 30-04-2015 à 12:59:31   

Reply

Marsh Posté le 30-04-2015 à 14:55:57    

Oui sorry, j'avais trouvé entre temps; juste avant de partir dej et je comptais venir te l'indiquer ! :)
 
Merci encore; heureusement que t'es là =)
 
Pour répondre à ta question concernant PERL plutôt que BAT, reprends moi si je me trompe mais il n'y a pas d'interpréteur PERL par défaut sur Windows; du coup je risque d'avoir du mal à exécuter ce script sur chacun de mes postes comme je l'imaginais.

Reply

Marsh Posté le 30-04-2015 à 15:04:48    

Effectivement sur Windows il faut installer Perl avant de pouvoir l'utiliser...
 
edit: Apparemment il existe une version portable (qu'il ne faut donc pas installer) de Strawberry Perl mais c'est un gros machin (102.2 MB)... Et faire le programme en C(++) pour avoir un exécutable ça me paraît pas plus facile (enfin selon si on s'y connait)...
 
Strawberry: http://strawberryperl.com/releases.html


Message édité par rat de combat le 30-04-2015 à 15:09:53
Reply

Marsh Posté le 30-04-2015 à 15:21:42    

Ouais effectivement ca ne va pas etre simple de déployer 100Mo sur les postes :D
 
Bon mon prochain défi avec batch va être d'identifier les lettres de lecteur des disques dur (pas lecteur réseau, ni cd, etc...)
 
Je viendrais t'embêter si je continue à rester bloqué sur le sujet ;-)


Message édité par bigstyle le 30-04-2015 à 15:26:48
Reply

Marsh Posté le 04-05-2015 à 15:11:04    

Me revoilà avec un nouveau souci; cette fois plutôt liée à la logique d'exécution dans un fichier BAT.
 
Voici le script me permettant de récupérer la liste des drives et d'exécuter un DIR pour chaque lecteur et le consolider dans un fichier global.

Code :
  1. @echo off
  2.   setlocal enabledelayedexpansion
  3.   WMIC LOGICALDISK where drivetype=3 get caption>%~n0.tmp
  4.   for /f "tokens=1-3 skip=1" %%a in ('type "%~n0.tmp"') do call :displayinfo %%a
  5. del "%~n0.tmp"
  6. echo FIN DU SCRIPT AVANT LE EOF
  7. goto :etapefin
  8. :displayinfo
  9. set drive=%1
  10. echo Le drive est %drive%
  11. echo lancement du DIR
  12. REM call dir /A HS /s /b %drive%\ >> d:\Dir_ALL.txt
  13. echo Fin du DIR
  14. :etape2
  15. echo voici l'etape 2
  16. echo blablalblablalballbabal
  17. :etapefin
  18. echo voici letape fin apres la boucle
  19. @pause
  20. @exit
  21. @pause


 
Ce que j'aimerai est que le "call displayinfo" se fasse uniquement sur la partie ":displayinfo" mais que la partie "etape 2" et le reste du script ne soient pas inclus dans la boucle qui fait le "do call displayinfo".
 
Est-ce que quelqu'un aurait une idée de comment indiquer la fin de l'exécution d'une boucle en bat ?  
 
Merci

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed