Remplissage d'un tableau dans un script batch DOS


33

Comment configurer une variable de tableau dans un script batch DOS? Je voudrais le charger avec une liste de noms de fichiers à traiter. Je voudrais vraiment garder cela aussi simple que possible. Merci.


1
Avez-vous vraiment besoin d'être compatible DOS ou pouvez-vous utiliser PowerShell?
Brian Knoblauch

1
Vous pouvez aussi utiliser vbscript assez facilement pour cela ...
JNK

@ Brian: DOS est requis. Découvrez la solution que j'ai postée.
Jim Fell

Si vous n'avez pas de cheveux, vous devriez certainement connaître la différence entre l'invite de commande et DOS
barlop

Réponses:


48

Je l'ai compris:

set FILE_LIST=(file1.dll file2.exe file3.dll file4.dll file5.dll)

set BIN_PATH="C:\Program Files\My App Folder\bin"
set BAK_PATH="C:\Program Files\My App Folder\bin\Backups"
set DEV_PATH="C:\My Dev Path\bin\Debug"

for %%i in %FILE_LIST% do copy %BIN_PATH%\%%i %BAK_PATH%
for %%i in %FILE_LIST% do copy %DEV_PATH%\%%i %BIN_PATH%

J'ai fait quelque chose comme ça il y a plusieurs années, alors il a fallu en décider un peu. (Au fait, je déteste réinventer la roue.) Maintenant que c'est affiché ici, j'espère que d'autres le trouveront utile aussi.


1
Eh bien, je n'ai jamais su que tu pouvais faire ça! Je l'ai essayé et il fonctionne!
Linker3000

Cela ne peut éventuellement pas fonctionner sous DOS. DOS ne fait pas de noms de fichiers longs (uniquement 8.3), et si je me souviens bien, DOS ne fait pas de guillemets dans les chemins de fichiers. Je ne dispose pas d'une installation MS-DOS pratique pour voir si elle prend en charge les tableaux utilisant une ()syntaxe.
un CVn

3
Bien que cela fonctionne pour vous, il convient de noter que ce n'est pas vraiment un tableau. C'est juste une chaîne qui est divisée en éléments individuels. Vous ne pouvez pas référencer les éléments directement en faisant quelque chose comme FILE_LIST[0].
aphorie

@ MichaelKjörling: FreeDOS peut prendre en charge les LFN et cite vraisemblablement, alors peut-être qu'il utilise cela?
Nathan Tuggy

@NathanTuggy Bon point. Néanmoins, dans ce cas, il serait préférable que ce soit explicite.
un CVn

12

Oui, vous pouvez faire des tableaux en batch. Bien qu'ils ne soient pas exactement comme les tableaux en C ou VB, vous POUVEZ le faire:

@echo off
setlocal enabledelayedexpansion

set  arrayline[0]=############
set  arrayline[1]=#..........#
set  arrayline[2]=#..........#
set  arrayline[3]=#..........#
set  arrayline[4]=#..........#
set  arrayline[5]=#..........#
set  arrayline[6]=#..........#
set  arrayline[7]=#..........#
set  arrayline[8]=#..........#
set  arrayline[9]=#..........#
set arrayline[10]=#..........#
set arrayline[11]=#..........#
set arrayline[12]=############

::read it using a FOR /L statement
for /l %%n in (0,1,12) do (
echo !arrayline[%%n]!
)
pause

1
c'est génial et inspirant .. je viens de faire une réponse qui s'appuie sur cela et remplit le tableau aussi
barlop

7

Dans le blog de Jakash3, Arrays in Batch explique comment émuler des tableaux dans l'invite de commande.

Un fichier de commandes nommé array.bat est inclus dans l'article, qui contient une bibliothèque de fonctions permettant de gérer les tableaux. Vous devrez sélectionner le texte de l'article et le coller dans le fichier chauve-souris.

Par exemple, le script de test suivant:

@echo off
set book[0]=Avatar
set book[1]=The Green Mile
set book[2]=The Count of Monte Cristo
call array.bat add book Babo
call array.bat len book length
echo I have %length% books you can borrow.
echo Pick one:
echo.
echo 0) Avatar
echo 1) The Green Mile
echo 2) The Count of Monte Cristo
echo 3) Babo
echo.
set /p pick=
call array.bat getitem book %pick% title
echo.
echo You picked %title%.

génère la sortie suivante:

image


1
ok bien que vous n'ayez pas listé le contenu de array.bat mais je vois qu'il est un peu long
barlop

4

Cela remplit un tableau et l’imprime

Vous pouvez utiliser noms1 noms2 noms3, plutôt que noms [1] noms [2] noms [3] en écrivant des noms! I! au lieu de noms [! i!]. Il produit le tableau en générant des noms de variables. Il n'y a pas de structure de tableau en batch. Mais c'est aussi ordonné que n'importe quelle structure de tableau, et le remplissage ou l'impression ressemble exactement à la façon dont on peuplerait ou imprimerait un tableau dans un langage approprié (qui possède en fait la structure du tableau!).

@echo off
setlocal enabledelayedexpansion enableextensions

set i=-1

for %%f in (bob, tom, joseph) do (
 set /a i=!i!+1
 set names[!i!]=%%f
)
set lastindex=!i!

for /L %%f in (0,1,!lastindex!) do ( 
  echo !names[%%f]!
)

le résultat-

c:\blah>a
bob
tom
joseph

c:\blah>

Quelques explications

Le setlocal enabledelayedexpansion enableextensionsavec le! Var! plutôt que% var% est nécessaire pour éviter tout comportement étrange, afin que les variables se comportent correctement dans un FOR ou un IF. C'est une bizarrerie avec les fichiers de commandes. Voir set /?où cela est mentionné plus loin.

C’est ce qui remplit le tableau et qui est assez simple pour quiconque connaît les tableaux. Vous pouvez également faire names[0]=bob names[1]=tom names[2]=josephsi l’une des beautés d’un tableau est la possibilité de remplir un tableau avec une boucle, ce que j’ai fait ici.

for %%f in (bob, tom, joseph) do (
 set /a i=!i!+1
 set names[!i!]=%%f
)
set lastindex=!i!

Cela affiche le tableau. %% f si vous le voyez, vous verrez qu'il passera de 0 au dernier index du tableau, en étapes de 1. ainsi seront imprimés les noms [0] noms [1] noms [2]

for /L %%f in (0,1,!lastindex!) do ( 
  echo !names[%%f]!
)

0

Pour ce que vous voulez faire, pourquoi ne pas utiliser une variable d'entrée pour chaque nom de fichier, que vous pouvez choisir avec les variables% 1% 2 etc., par exemple: mybat.bat fichier1.nam fichier2.nam etc.

Vous pouvez ensuite utiliser ces variables dans une boucle, mais vous devez uniquement utiliser% 1 comme paramètre principal, car vous pouvez utiliser SHIFT pour amener les autres variables dans la "position"% 1, avec un test de null (fin des variables) avec quelque chose comme si "X% 1" == "X"

par exemple:

:LOOP
IF "X%1" == "X" GOTO DONE
COPY %1 C:\TARGET.DIR
SHIFT
GOTO LOOP
:DONE

0

Si vous enregistrez la liste de fichiers dans le fichier filelist.txt, vous pouvez FORlire et traiter chaque ligne du fichier, telle que

FOR /F "delims=|" %i  IN (filelist.txt) DO @echo %i

pour imprimer chaque ligne d'un fichier (jusqu'au premier "|" de la ligne. Si vous ne spécifiez pas votre propre délimiteur, l'espace et la tabulation seront utilisés, ainsi, à moins que vos chemins ne comportent aucun espace, vous devez spécifier un caractère qui n'apparaîtra pas dans le fichier pour obtenir des lignes complètes).


for / f est en fait une fonctionnalité de Windows 2000 et versions ultérieures. Ce n'est pas sous DOS.
wendy.krieger

0

Dans un de vos commentaires à une réponse, vous dites:

Je suis en train de travailler sur le développement, et à cause de la nature complexe de l'application à chaque fois et je veux tester une construction (ce qui est souvent le cas), je dois copier cinq fichiers du répertoire binaire de construction vers le répertoire d'installation. Cela devient fastidieux. À l'heure actuelle, les noms de fichiers sont codés en dur dans mon script de traitement par lots, mais j'aimerais les placer dans un tableau afin de faciliter la maintenance du script.

Je crois que ce que vous recherchez est un Makefile et éventuellement cygwin pour vous donner une coque décente (bash, ou quelle que soit votre saveur).


0

Remplace les chaînes et les lettres dans le texte.

Essayez la boucle en développant le texte dans un corps et en remplaçant var par var. Glissez-déposez le fichier texte pour que% 1 soit entré par l'utilisateur en appelant la commande set.

@echo off
setlocal EnableDelayedExpansion
set /p a= enter letter to change:
set /p b= letter to change to:
set /p input=<%1
for /f %%c in ("!input:~!") do (
set "code=!input:%a%=%b%!"
echo !code!>myfile.txt
)

0

Quelque chose comme ça dans un fichier batch? Sélectionnez un fichier dans un dossier. << est un commentaire, pas de code

:selectapk
SETLOCAL ENABLEDELAYEDEXPANSION      << DELAYED EXPANSION on for counter in For loop
SET /A MAXITEM=0
Echo.
Echo Found these APK files in "add_apk_here" folder.
Echo.
For %%a in (add_apk_here/*.apk) do (
 Set /A MAXITEM+=1
 Set MENUITEM!MAXITEM!=%%a        << Fill n local env vars, one for each file, called MENUITEM1...n
 Echo    !MAXITEM!. %%a
)
Echo.
If !MAXITEM!==0 Echo No APK in "add_apk_here" folder & call :delay & Goto start   << No apk files then go back
SET /P CHOICE=Select APK to work on: 
SET MENUITEM=!MENUITEM%CHOICE%!      << Get the stored filename from MENUITEMx
SETLOCAL DISABLEDELAYEDEXPANSION     << Very important for next ENDLOCAL that doesn't like the delayedexpansion var
ENDLOCAL & SET apk=%MENUITEM%        << put the local MENUITEM var into the global apk var
goto start

:delay
REM %1 like Call :delay 5
SETLOCAL
SET N=%1
If Not Defined N Set N=2
Ping -n %N% -w 1000 127.255.255.255 > nul
ENDLOCAL
Exit /b

0

Vous ne pouvez pas vraiment créer de tableau dans l'invite de commande (et ce n'est pas vraiment un DOS si vous n'exécutez pas Windows 3.1). Cependant, vous pouvez effectuer un traitement basé sur les jeux avec la commande FOR.

Pour créer la liste des fichiers à traiter, vous pouvez créer manuellement un fichier texte à traiter ou utiliser la dir /b <mask>commande située dans la boucle FOR.

Quelque chose que j'ai appris à la dure avec FOR - vous devez utiliser une variable SINGLE CHARACTER comme curseur!


+1 vous commentez qu'un vote négatif devrait être expliqué. En outre, vous avez écrit "vous devez utiliser une variable SINGLE CHARACTER comme curseur!" <- vous voulez dire que votre index n'est pas votre curseur
barlop

1
Notez également que s’il s’agit d’un disque de démarrage Win9X, il s’agit de DOS (DOS 7). Et Windows 9X fonctionnait toujours sous DOS. Et vous pourriez ajouter une ligne à. Je pense que c’était msdos.sys comme bootscan = 0 et bootgui = 0 qui l’empêcheraient de démarrer sous Windows et de démarrer directement à l’aide du DOS.
Barlop

0

Consultez la documentation Microsoft sur le commande FOR batch . Vous pouvez utiliser FOR pour parcourir un ensemble de répertoires, des fichiers d’un répertoire ou des fichiers d’un répertoire et de tous ses sous-répertoires.

Par défaut, FOR gère un ensemble ou uniquement des fichiers:

FOR %f IN (*.txt) DO ECHO %f

Ou, pour récursif:

FOR /R %f IN (*.txt) DO ECHO %f

ou, pour les répertoires seulement:

FOR /D %d DO ECHO %d

Malheureusement, toutes ces options couvrent tous les domaines. Je suis en train de travailler sur le développement, et à cause de la nature complexe de l'application à chaque fois et je veux tester une construction (ce qui est souvent le cas), je dois copier cinq fichiers du répertoire binaire de construction vers le répertoire d'installation. Cela devient fastidieux. À l'heure actuelle, les noms de fichiers sont codés en dur dans mon script de traitement par lots, mais j'aimerais les placer dans un tableau afin de faciliter la maintenance du script.
Jim Fell

0

c’est un petit fichier de débogage que j’ai fait pendant un certain temps pour tester le tableau de mon jeu de remorquage en tic tac dans BATCH / CMD. il peut lire et écrire à partir d'un tableau sans aller trop gros et compliqué sur le code.

l'utiliser est simple:

Ecrire dans un tableau

  1. donnez-lui un fichier ou modifiez-le pour importer autre chose.
  2. donnez un nom au tableau.
  3. et votre fait.

Lecture d'un tableau

  1. Indiquez la taille du tableau que vous souhaitez lire ou une partie de celui-ci.
  2. Mettez le nom du tableau avec %% a dans le nom
  3. et votre fait.

Code:

@echo off
setlocal EnableDelayedExpansion

set ID=0

::              Reader                   ::
:: It reads the file called input.txt    ::
:: and stores it in a new variable that  ::
:: for everytime it goes over it it is a ::
:: new ID (Slot in the array).           ::

For /F %%A in (input.txt) do ( 
    set /a ID=ID+1
    set Input!ID!= %%A

    echo !ID! : %%A
)


::             Writer                     ::
:: this is to read all Slots in the array ::
:: and puts it on the screen.             ::

for /L %%a in (1,1,!ID!) do (
    echo !Input%%a!
)
pause>nul
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.