Preenchendo uma matriz no script de lote do DOS

33

Como posso configurar uma variável de matriz em um script em lotes do DOS? Eu gostaria de carregá-lo com uma lista de nomes de arquivos para processar. Eu realmente gostaria de manter isso o mais simples possível. Obrigado.

Jim Fell
fonte
1
Você realmente precisa ser compatível com DOS ou pode usar o PowerShell?
precisa saber é o seguinte
1
Você também pode usar VBScript muito facilmente por isso ...
JNK
@ Brian: DOS é necessário. Confira a solução que publiquei.
Jim caiu
Se você não tem cabelo, então certamente você deve saber a diferença entre o prompt de comando e DOS
barlop

Respostas:

48

Eu descobri:

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%

Eu fiz algo assim há vários anos, então demorou um pouco para descobrir. (btw, eu odeio reinventar a roda.) Agora que foi publicado aqui, espero que outros o achem útil também.

Jim Fell
fonte
1
Bem, eu nunca soube que você poderia fazer isso! Eu tentei e funciona!
precisa saber é o seguinte
Isso não pode funcionar no DOS. O DOS não usa nomes de arquivos longos (apenas 8.3) e, pelo que me lembro, o DOS também não faz aspas nos caminhos dos arquivos. Não tenho uma instalação do MS-DOS à mão para ver se ela suporta matrizes usando uma ()sintaxe.
um CVn
3
Embora isso funcione para o seu propósito, deve-se notar que não é realmente uma matriz. É apenas uma string que está sendo dividida em elementos individuais. Você não pode referenciar os elementos diretamente fazendo algo parecido FILE_LIST[0].
Aphoria
@ MichaelKjörling: O FreeDOS pode suportar LFNs e presumivelmente citações, então talvez ele esteja usando isso?
Nathan Tuggy
@NathanTuggy Bom ponto. Ainda assim, seria melhor nesse caso se fosse explicitado.
um CVn
12

Sim, você pode fazer matrizes em lote. Enquanto eles não são exatamente como matrizes em C ou VB, você pode fazê-lo:

@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
Patrick Jackson
fonte
1
que é incrível e inspring .. i acabou de fazer uma resposta que constrói sobre isso e preenche a matriz também
barlop
7

No blog de Jakash3, matrizes em lote descreve como emular matrizes no prompt de comando.

Um arquivo em lotes denominado array.bat está incluído no artigo, que contém uma biblioteca de funções usadas para manipular matrizes. Você precisará selecionar o texto no artigo e colá-lo dentro do arquivo bat.

Por exemplo, o seguinte script de teste:

@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%.

gera a seguinte saída:

imagem

harrymc
fonte
1
ok que você não tenha listado o conteúdo de array.bat embora eu ver que é um pouco longo
barlop
4

Isso preenche uma matriz e a imprime

Você pode usar nomes1 nomes2 nomes3, em vez de nomes [1] nomes [2] nomes [3] escrevendo nomes! I! em vez de nomes [! i!]. Produz a matriz gerando nomes de variáveis. Não há uma estrutura de matriz no lote. Mas é tão elegante quanto qualquer estrutura de matriz, e preencher ou imprimir se parece exatamente com a forma como alguém preencheria ou imprimiria uma matriz em uma linguagem adequada (que na verdade possui a estrutura da matriz!)

@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]!
)

a saída-

c:\blah>a
bob
tom
joseph

c:\blah>

Alguma explicação

O setlocal enabledelayedexpansion enableextensionscom o! Var! em vez de% var% é necessário para evitar comportamentos estranhos, para que as variáveis ​​se comportem corretamente quando dentro de um FOR ou um IF. É uma raridade com arquivos em lote. Veja set /?onde isso é mencionado mais adiante.

É isso que preenche a matriz e é bastante direto para quem sabe sobre matrizes. Você também pode fazer, names[0]=bob names[1]=tom names[2]=josephembora uma das belezas de uma matriz seja a capacidade de preencher uma matriz com um loop, o que eu fiz aqui.

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

Isso exibe a matriz. %% f se você repetir, verá de 0 ao último índice da matriz, nas etapas de 1. assim, imprimirá os nomes [0] names [1] names [2]

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

Para o que você deseja fazer, que tal usar uma variável de entrada para cada nome de arquivo, que você pode selecionar com as variáveis% 1% 2 etc., por exemplo: mybat.bat file1.nam file2.nam etc.

Em seguida, você pode usar essas variáveis ​​em um loop, mas só precisa usar% 1 como o parâmetro principal, pois você pode usar SHIFT para trazer as outras variáveis ​​para a% 1 'posição', fazendo um teste para null (final de variáveis) com algo como se "X% 1" == "X"

por exemplo:

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

Se você salvar a lista de arquivos no arquivo filelist.txt, poderá FORler e processar cada linha do arquivo, como

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

para imprimir cada linha de um arquivo (até o primeiro "|" na linha. Se você não especificar seu próprio delimitador, serão utilizados espaço e guia; portanto, a menos que seus caminhos não tenham espaços, é necessário especificar um caractere que não aparecerá no arquivo para obter linhas completas).

Neal
fonte
para / f é realmente um recurso do Windows 2000 e posterior. Não está no DOS.
Wendy.krieger
0

Em um dos seus comentários para uma resposta, você diz:

Estou fazendo um trabalho de desenvolvimento e, devido à natureza complexa do aplicativo, todas as vezes e quero testar uma compilação (que geralmente é), tenho que copiar cinco arquivos do diretório binário de construção para o diretório binário de instalação. Isso fica entediante. No momento, tenho os nomes dos arquivos codificados no meu script em lotes, mas gostaria de colocá-los em uma matriz para facilitar a manutenção do script.

Acredito que o que você está procurando é um Makefile e, possivelmente, o cygwin para lhe dar uma casca decente (bash ou qualquer que seja o seu sabor).

Lorenzog
fonte
0

Substitua as strings e a letra no texto.

Tente o loop expandindo o texto para um corpo for e substituindo var por var. Arraste e solte o arquivo de texto para que% 1 seja a entrada do usuário, chamando o comando 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
)
mordex
fonte
0

Algo assim em um arquivo em lotes? Selecione um arquivo em uma pasta. << é comentário, nenhum código

: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
tweakradje
fonte
0

Você não pode realmente fazer uma matriz no prompt de comando (e também não é realmente DOS, a menos que esteja executando o Windows 3.1). No entanto, você pode executar o processamento baseado em conjunto com o comando FOR.

Para criar a lista de arquivos a serem processados, você pode criar manualmente um arquivo de texto a ser processado ou usar o dir /b <mask>comando dentro do loop FOR.

Algo que aprendi da maneira mais difícil com FOR - você precisa usar uma variável SINGLE CHARACTER como cursor!

JNK
fonte
Você comenta com +1 que um voto negativo deve ser explicado. Além disso, você escreveu "você precisa usar uma variável SINGLE CHARACTER como cursor!" <- você quer dizer que o seu índice não como seu cursor
barlop
1
Observe também que, se for um disco de inicialização do Win9X, o DOS (DOS 7). E ainda se dizia que o Windows 9X era executado no DOS. E você pode adicionar uma linha a eu acho que foi o msdos.sys, como bootscan = 0 e bootgui = 0, que interromperiam a inicialização no Windows e inicializariam diretamente em um prompt do DOS.
barlop
0

Confira a documentação da Microsoft no comando FOR batch . Você pode usar FOR para iterar sobre um conjunto de diretórios, arquivos em um diretório ou arquivos em um diretório e todos os seus subdiretórios.

Por padrão, FOR manipula conjunto ou apenas arquivos:

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

Ou, para recursivo:

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

ou, apenas para diretórios:

FOR /D %d DO ECHO %d
pesado
fonte
Infelizmente, todas essas opções são completas para seus respectivos escopos. Estou fazendo um trabalho de desenvolvimento e, devido à natureza complexa do aplicativo, todas as vezes e quero testar uma compilação (que geralmente é), tenho que copiar cinco arquivos do diretório binário de construção para o diretório binário de instalação. Isso fica entediante. No momento, tenho os nomes dos arquivos codificados no meu script em lote, mas gostaria de colocá-los em uma matriz para facilitar a manutenção do script.
Jim Fell
0

este é um pequeno arquivo de depuração que fiz um tempo para testar a matriz do meu jogo de reboque tic tac em BATCH / CMD. ele pode ler e gravar de e para uma matriz sem ser grande e complicada no código.

usá-lo é simples:

Gravando em uma matriz

  1. atribua um arquivo ou modifique-o para importar outra coisa.
  2. dê um nome à matriz.
  3. e pronto.

Lendo de uma matriz

  1. Dê o tamanho da matriz ou parte dela que você deseja ler.
  2. Coloque o nome da matriz com %% a no nome
  3. e pronto.

Código:

@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
Elforax
fonte