2008-09-02 9 views
154

J'ai un ensemble de noms de fichiers de base, pour chaque nom 'f' il y a exactement deux fichiers, 'f.in' et 'f.out'. Je veux écrire un fichier batch (sous Windows XP) qui passe par tous les noms de fichiers, pour chacun, il doit:Comment faire une boucle dans les fichiers correspondant au caractère générique dans le fichier de commandes

  • Affiche le nom de base « f »
  • Effectuer une action sur « f.in »
  • Effectuer une autre action sur « f.out »

Je n'ai aucune façon à la liste de l'ensemble des noms de fichiers de base, autre que pour rechercher * .in (ou * .out) par exemple.

+7

Je ne veux vraiment pas être ce mec après 111/0 votes, mais votre question ne montre aucune recherche whatsoeaver – Blauhirn

Répondre

234

En supposant que vous avez deux programmes qui traitent les deux fichiers, process_in.exe et process_out.exe:

for %%f in (*.in) do (
    echo %%~nf 
    process_in "%%~nf.in" 
    process_out "%%~nf.out" 
) 

%% nf est un modificateur de substitution qui étend% f à un nom de fichier uniquement. Voir les autres modificateurs dans https://technet.microsoft.com/en-us/library/bb490909.aspx (au milieu de la page) ou juste dans la réponse suivante.

+28

Utilisez un single '%' si vous tapez ceci sur la ligne de commande. Je sais que le PO ne pose pas de questions sur la ligne de commande, mais c'est ce que je cherchais lorsque cette question est apparue en haut de ma recherche Google. D'autres peuvent apprécier ce peu. – Jason

+1

Pourriez-vous expliquer la syntaxe? La variable de boucle est déclarée '%% f' pourquoi est-elle' %% ~ nf' plus tard? –

+3

@ColonelPanic - il y a une poignée de modificateurs '~' pour faire les choses, comme dans mon exemple, il suffit d'obtenir le nom du fichier. C'est juste une habitude pour moi de l'utiliser dans le cas où le '*' fait le chemin complet ou quelque chose. Il existe une poignée de ces modificateurs (au milieu de la page): http://www.microsoft.com/resources/documentation/windows/xp/all/proddocs/en-us/batch.mspx?mfr=true –

4

La manière la plus simple, comme je le vois, est d'utiliser une boucle for qui appelle un deuxième fichier batch pour le traitement, en passant ce deuxième fichier le nom de base.

Selon le pour /? help, basename peut être extrait en utilisant l'option nifty ~ n. Ainsi, le script de base lirait:

for %%f in (*.in) do call process.cmd %%~nf 

Puis, en process.cmd, supposons que% 0 contient le nom de base et d'agir en conséquence. Par exemple:

echo The file is %0 
copy %0.in %0.out 
ren %0.out monkeys_are_cool.txt 

Il pourrait y avoir une meilleure façon de le faire dans un script, mais je l'ai toujours été un peu flou sur la façon de tirer des commandes multiples en une seule boucle dans un fichier batch.

EDIT: C'est fantastique! J'avais raté la page dans les documents qui montraient que vous pouviez faire des blocs multi-lignes dans une boucle FOR. Je vais aller faire revenir en arrière et réécrire certains fichiers batch maintenant ...

3

Il est un outil généralement utilisé dans les serveurs MS (pour autant que je me souvienne) appelé forfiles:

Le lien ci-dessus contient aide ainsi qu'un lien vers la page de téléchargement de Microsoft.

68

Vous pouvez utiliser cette ligne pour imprimer le contenu de votre bureau:

FOR %%I in (C:\windows\desktop\*.*) DO echo %%I 

Une fois que vous avez la variable %%I il est facile d'effectuer une commande sur elle (il suffit de remplacer le mot écho avec votre programme)

En outre, la substitution de variables des références a été améliorée Vous pouvez maintenant utiliser la syntaxe suivante en option:

%~I   - expands %I removing any surrounding quotes (") 
%~fI  - expands %I to a fully qualified path name 
%~dI  - expands %I to a drive letter only 
%~pI  - expands %I to a path only (directory with \) 
%~nI  - expands %I to a file name only 
%~xI  - expands %I to a file extension only 
%~sI  - expanded path contains short names only 
%~aI  - expands %I to file attributes of file 
%~tI  - expands %I to date/time of file 
%~zI  - expands %I to size of file 
%~$PATH:I - searches the directories listed in the PATH 
       environment variable and expands %I to the 
       fully qualified name of the first one found. 
       If the environment variable name is not 
       defined or the file is not found by the 
       search, then this modifier expands to the 
       empty string 


[https://ss64.com/nt/syntax-args.html][1] 

Dans les exemples ci-dessus, %I et PATH peuvent être remplacés par d'autres valeurs valides . La syntaxe %~ est terminée par un nom de variable FOR valide. La sélection de noms de variables majuscules comme %I le rend plus lisible et évite la confusion avec les modificateurs, qui ne sont pas sensibles à la casse.

Vous pouvez obtenir la documentation complète en tapant FOR /?

+0

Cela ne semble pas fonctionner. '%% J'étais inattendu pour le moment.' – Brad

+2

@Brad si vous utilisez ceci dans la ligne de commande (et non dans un fichier batch), alors utilisez '% I' au lieu de' %% I' – doubleDown

3

Expansion sur le poste Nathans. Ce qui suit fera le lot de travail dans un fichier batch.

@echo off 

if %1.==Sub. goto %2 

for %%f in (*.in) do call %0 Sub action %%~nf 
goto end 

:action 
echo The file is %3 
copy %3.in %3.out 
ren %3.out monkeys_are_cool.txt 

:end 
0

Le code ci-dessous les filtres commençant par les noms de fichiers sous-chaîne donnée. Il pourrait être modifié pour répondre à différents besoins en travaillant sur l'extraction de sous-chaîne subfname et instruction IF:

echo off 
rem filter all files not starting with the prefix 'dat' 
setlocal enabledelayedexpansion 
FOR /R your-folder-fullpath %%F IN (*.*) DO (
set fname=%%~nF 
set subfname=!fname:~0,3! 
IF NOT "!subfname!" == "dat" echo "%%F" 
) 
pause 
0

Faisant écho f.in et f.out va séparer le concept de ce à boucle et quoi ne pas boucle lorsqu'il est utilisé dans un pour/f boucle.

::Get the files seperated 
echo f.in>files_to_pass_through.txt 
echo f.out>>files_to_pass_through.txt 

for /F %%a in (files_to_pass_through.txt) do (
for /R %%b in (*.*) do (
if "%%a" NEQ "%%b" (
echo %%b>>dont_pass_through_these.txt 
) 
) 
) 
::I'm assuming the base name is the whole string "f". 
::If I'm right then all the files begin with "f". 
::So all you have to do is display "f". right? 
::But that would be too easy. 
::Let's do this the right way. 
for /f %%C in (dont_pass_through_these.txt) 
::displays the filename and not the extention 
echo %~nC 
) 

Bien que vous n'avez pas demandé, une bonne façon de passer des commandes dans f.in et f.out serait ...

for /F %%D "tokens=*" in (dont_pass_through_these.txt) do (
for /F %%E in (%%D) do (
start /wait %%E 
) 
) 

Un lien vers toutes les commandes Windows XP: Je m'excuse si je n'ai pas répondu correctement à cette question. La question était très difficile à lire pour moi.

Questions connexes