Wypełnianie tablicy w skrypcie wsadowym DOS

33

Jak ustawić zmienną tablicową w skrypcie wsadowym DOS? Chciałbym załadować go z listą nazw plików do przetworzenia. Naprawdę chciałbym, aby było to tak proste, jak to możliwe. Dziękuję Ci.

Jim Fell
źródło
1
Czy naprawdę potrzebujesz być kompatybilny z DOS, czy możesz używać PowerShell?
Brian Knoblauch,
1
Do tego możesz też całkiem łatwo użyć vbscript ...
JNK
@Brian: DOS jest wymagany. Sprawdź opublikowane przeze mnie rozwiązanie.
Jim Fell,
Jeśli nie masz włosów, z pewnością powinieneś znać różnicę między
wierszem

Odpowiedzi:

48

Rozgryzłem to:

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%

Zrobiłem coś takiego kilka lat temu, więc trochę to wymyśliłem. (przy okazji, nie znoszę wymyślać koła na nowo.) Teraz, gdy jest opublikowany tutaj, mam nadzieję, że inni również uznają to za przydatne.

Jim Fell
źródło
1
Nigdy nie wiedziałem, że możesz to zrobić! Próbowałem i działa!
Linker3000
To nie może działać w systemie DOS. DOS nie robi długich nazw plików (tylko 8.3) i, jak pamiętam, DOS również nie robi cudzysłowów w ścieżkach plików. Nie mam pod ręką instalacji MS-DOS, aby sprawdzić, czy obsługuje tablice przy użyciu ()składni.
CVn
3
Chociaż to działa w twoim przypadku, należy zauważyć, że tak naprawdę nie jest to tablica. To tylko struna dzielona na poszczególne elementy. Nie można bezpośrednio odwoływać się do elementów, wykonując coś takiego FILE_LIST[0].
aforia
@ MichaelKjörling: FreeDOS może obsługiwać numery LFN i prawdopodobnie cytaty, więc może używa tego?
Nathan Tuggy
@NathanTuggy Dobra uwaga. W takim przypadku byłoby lepiej, gdyby zostało to wyraźnie określone.
CVn
12

Tak, możesz wykonywać tablice wsadowo. Chociaż nie są dokładnie takie jak tablice w C lub VB, MOŻESZ to zrobić:

@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
źródło
1
to jest niesamowite i inspirujące .. właśnie zrobiłem odpowiedź, która na tym opiera się i wypełnia również tablicę
barlop
7

Z bloga Jakash3, Arrays in Batch opisuje, jak emulować tablice w wierszu polecenia.

Plik wsadowy o nazwie array.bat znajduje się w artykule, który zawiera bibliotekę funkcji używanych do obsługi tablic. Musisz zaznaczyć tekst w artykule i wkleić go do pliku nietoperza.

Na przykład następujący skrypt testowy:

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

generuje następujące dane wyjściowe:

obraz

harrymc
źródło
1
ok, chociaż nie wymieniono zawartości tablicy.bat, choć widzę, że jest trochę długa
barlop
4

Spowoduje to zapełnienie tablicy i wydrukowanie jej

Możesz użyć nazwy1 nazwy2 nazwy3 zamiast nazw [1] nazw [2] nazw [3], pisząc nazwy! zamiast nazw [! i!]. Tworzy tablicę, generując nazwy zmiennych. Partia nie zawiera struktury tablic. Ale jest tak schludny, jak każda struktura tablic, a zapełnianie lub drukowanie wygląda dokładnie tak, jak można wypełnić lub wydrukować tablicę w odpowiednim języku (który faktycznie ma strukturę tablic!)

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

wyjście-

c:\blah>a
bob
tom
joseph

c:\blah>

Niektóre wyjaśnienia

Z setlocal enabledelayedexpansion enableextensions! Var! zamiast% var% jest konieczne, aby zapobiec nieparzystemu zachowaniu, tak aby zmienne zachowywały się poprawnie w FOR lub IF. To dziwne z plikami wsadowymi. Zobacz, set /?gdzie jest to wspomniane dalej.

To właśnie zapełnia tablicę i jest całkiem proste dla każdego, kto wie o tablicach. Możesz także zrobić, names[0]=bob names[1]=tom names[2]=josephchoć jedną z piękności tablicy jest możliwość zapełnienia tablicy pętlą, co właśnie zrobiłem tutaj.

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

Wyświetla tablicę. %% f, jeśli wyświetlisz echo, przejdzie od 0 do ostatniego indeksu tablicy, w krokach co 1. więc wydrukuje nazwy [0] nazwy [1] nazwy [2]

for /L %%f in (0,1,!lastindex!) do ( 
  echo !names[%%f]!
)
barlop
źródło
0

W tym, co chcesz zrobić, co powiesz na użycie zmiennej wejściowej dla każdej nazwy pliku, którą możesz pobrać za pomocą zmiennych% 1% 2 itd. Np. Mybat.bat plik1.nam plik2.nam itp.

Następnie można użyć tych zmiennych w pętli, ale wystarczy użyć% 1 jako parametru głównego, ponieważ można użyć SHIFT, aby ustawić inne zmienne w pozycji „% 1”, testując wartość null (koniec zmiennych) z czymś jak JEŻELI „X% 1” == „X”

na przykład:

:LOOP
IF "X%1" == "X" GOTO DONE
COPY %1 C:\TARGET.DIR
SHIFT
GOTO LOOP
:DONE
Linker3000
źródło
0

Jeśli zapiszesz listę plików w pliku filelist.txt, możesz FORprzeczytać i przetworzyć każdą linię pliku, na przykład

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

do wydrukowania każdego wiersza pliku (do pierwszego „|” w wierszu. Jeśli nie określisz własnego ogranicznika, zostaną użyte spacje i tabulatory, więc jeśli ścieżki nie mają spacji, musisz podać znak które nie pojawią się w pliku, aby uzyskać pełne linie).

Neal
źródło
for / f to tak naprawdę funkcja systemu Windows 2000 i nowszych. Nie ma go w systemie DOS.
wendy.krieger
0

W jednym z komentarzy do odpowiedzi, którą podajesz,

Robię prace programistyczne, a ze względu na złożony charakter aplikacji za każdym razem i chcę przetestować kompilację (co często bywa), muszę skopiować pięć plików z katalogu binarnego kompilacji do katalogu binarnego instalacji. To staje się nudne. W tej chwili mam nazwy plików zapisane na stałe w skrypcie wsadowym, ale chciałbym umieścić je w tablicy, aby ułatwić obsługę skryptu.

Uważam, że to, czego szukasz, to Makefile i prawdopodobnie cygwin, który da ci przyzwoitą skorupkę (bash lub cokolwiek innego).

lorenzog
źródło
0

Zamień ciągi i literę w tekście.

Wypróbuj pętlę, rozwijając tekst do ciała i zastępując var var. Przeciągnij i upuść plik tekstowy, aby% 1 był wprowadzany przez użytkownika przez wywołanie polecenia 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
źródło
0

Coś takiego w pliku wsadowym? Wybierz plik w folderze. << to komentarz, bez kodu

: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
źródło
0

Naprawdę nie możesz zrobić tablicy w wierszu polecenia (a także tak naprawdę nie jest to DOS, chyba że używasz systemu Windows 3.1). Można jednak przetwarzać na podstawie zestawu za pomocą polecenia FOR.

Aby utworzyć listę plików do przetworzenia, możesz ręcznie utworzyć plik tekstowy do przetworzenia lub użyć dir /b <mask>polecenia w pętli FOR.

Czego nauczyłem się na własnej skórze z FOR - musisz użyć zmiennej POJEDYNCZEGO ZNAKU jako kursora!

JNK
źródło
+1 komentujesz, że opinia powinna zostać wyjaśniona. Napisałeś także: „musisz użyć zmiennej POJEDYNCZEGO ZNAKU jako kursora!” <- masz na myśli jako swój indeks, a nie kursor
barlop
1
Zauważ też, że jeśli jest to dysk rozruchowy Win9X, to jest to DOS (DOS 7). A Windows 9X nadal miał działać pod DOS. I możesz dodać linię do, myślę, że to msdos.sys, takie jak bootscan = 0 i bootgui = 0, które przestałyby uruchamiać się w systemie Windows i uruchamiały się bezpośrednio do monitu DOS.
barlop
0

Sprawdź dokumentację Microsoft dotyczącą polecenia wsadowego FOR . Za pomocą FOR można iterować po zestawie katalogów, plikach w katalogu lub plikach w katalogu i wszystkich jego podkatalogach.

Domyślnie dla uchwytów ustawia lub po prostu pliki:

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

Lub dla rekurencyjnego:

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

lub tylko dla katalogów:

FOR /D %d DO ECHO %d
ciężki
źródło
Niestety wszystkie te opcje obejmują wszystkie ich zakresy. Robię prace programistyczne, a ze względu na złożony charakter aplikacji za każdym razem i chcę przetestować kompilację (co często bywa), muszę skopiować pięć plików z katalogu binarnego kompilacji do katalogu binarnego instalacji. To staje się nudne. W tej chwili mam nazwy plików zapisane na stałe w skrypcie wsadowym, ale chciałbym umieścić je w tablicy, aby ułatwić obsługę skryptu.
Jim Fell,
0

to jest mały plik do debugowania, który poświęciłem chwilę na przetestowanie tablicy z mojej gry Tic Tac w BATCH / CMD. potrafi czytać i zapisywać do iz tablicy bez dużych i skomplikowanych kodów.

korzystanie z niego jest proste:

Zapis do tablicy

  1. podaj plik lub zmodyfikuj go, aby zaimportować coś innego.
  2. nadaj tablicy nazwę.
  3. i gotowe.

Czytanie z tablicy

  1. Podaj rozmiar tablicy lub jej część, którą chcesz przeczytać.
  2. Wpisz nazwę tablicy z %% a w nazwie
  3. i gotowe.

Kod:

@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
źródło