Folder Prey has
"Deer.txt",
"Antelope.txt",
"Rabbit.txt"
Folder Predator has
"Shark.txt",
"Bear.txt",
"Cougar.txt"
Folder Habitat has
"Forest.txt",
"Ocean.txt",
"Desert.txt"
Jak wygenerować wszystkie 27 możliwych kombinacji przy użyciu pliku .bat? Problem polega na tym, że liczba folderów nie jest statyczna. Ktoś może później dodać Folder Food lub usunąć Folder Habitat. Czy można by zapisać plik .bat, aby sobie z tym poradzić?
Dane wyjściowe będą:
Deer_Shark_Forest
Deer_Shark_Ocean
Deer_Shark_Desert
Deer_Bear_Forest
Deer_Bear_Ocean
Deer_Bear_Desert
Deer_Cougar_Forest
Deer_Cougar_Ocean
Deer_Cougar_Desert
Antelope_Shark_Forest
Antelope_Shark_Ocean
Antelope_Shark_Desert
Antelope_Bear_Forest
Antelope_Bear_Ocean
Antelope_Bear_Desert
Antelope_Cougar_Forest
Antelope_Cougar_Ocean
Antelope_Cougar_Desert
Rabbit_Shark_Forest
Rabbit_Shark_Ocean
Rabbit_Shark_Desert
Rabbit_Bear_Forest
Rabbit_Bear_Ocean
Rabbit_Bear_Desert
Rabbit_Cougar_Forest
Rabbit_Cougar_Ocean
Rabbit_Cougar_Desert
Zapewniam cię, że to nie jest zadanie domowe. Chciałbym napisać to jako plik wsadowy.
windows
batch-file
Rick Tan
źródło
źródło
Odpowiedzi:
Możesz to zrobić za pomocą następującego pliku wsadowego:
Spowoduje to utworzenie pliku o nazwie
temp1.txt
. (Oczywiście skrypt można w trywialny sposób zmodyfikować, aby używał innej nazwy pliku i / lub wyświetlał wyniki na ekranie.) Oto wynik, który otrzymałem:Uwagi:
*
symbol wieloznaczny, więc kolejność danych wyjściowych zależy od kolejności, w której system Windows rozwija symbol wieloznaczny. W moim systemie dane alfabetyczne pozycje katalogu*
są rozwijane w kolejności alfabetycznej. Może to być inne w systemach używających języków innych niż angielski i / lub może być zmieniane przez ustawienie konfiguracji. Dla celów następnych dwóch pocisków założę, że użyto kolejności alfabetycznej.setlocal enabledelayedexpansion
pozwala nam obsługiwać zmienne w pętlach.copy nul temp2.txt > nul
tworzy drugi tymczasowy plik roboczy.> nul
Hamuje normalny1 file(s) copied.
komunikat o stanie.for /d %%D in (*) do
zapętla wszystkie foldery w bieżącym katalogu. Zmienna%%D
będzie kolejno przyjąć wartościHabitat
,Predator
orazPrey
- czy cokolwiek foldery są w bieżącym katalogu po uruchomieniu pliku wsadowego.for %%F in ("%%D"\*) do
zapętla wszystkie pliki w katalogu%%D
; tzn. katalog, na który patrzymy obecnie z zewnętrznej pętli. Zmienna%%F
będzie kolejno wziąć na wartościach takich jakHabitat\Desert.txt
,Habitat\Forest.txt
iHabitat\Ocean.txt
. Cudzysłowy pozwalają na to, nawet jeśli nazwa katalogu zawiera spacje.Jeśli w folderze znajdują się inne pliki, zostaną one również uwzględnione. Jeśli chcesz patrzeć tylko na
.txt
pliki, zmieńfor
instrukcję nafor %%F in ("%%D"\*.txt) do
.!first_pass!
jest tylko zmiennąfirst_pass
. Normalnie byłby napisany%first_pass%
, ale musimy użyć tej składni, ponieważ jesteśmy w pętli. (Działa to tylko dlatego, że włączyliśmy go, zsetlocal enabledelayedexpansion
.)first_pass
jestyes
podczas przetwarzania pierwszego katalogu; tjHabitat
. W tym przypadku po prostu zapisujemy nazwętemp2.txt
pliku; więc po zakończeniufor %%F in ("%%D"\*) do
pętlitemp2.txt
będzie zawierać dlatego%%~nF
ocenia się tylko do pliku bazy n ame części ścieżki w pliku%%F
. Jeśli chcesz dołączyć do.txt
e x napięć, użyj%%~nxF
zamiast%%~nF
.for /d %%D
) po raz drugi i trzeci (itp.),first_pass
Jestno
itemp1.txt
jesttemp2.txt
z poprzedniego przejścia.for /f "delims=" %%L in (temp1.txt) do
, który zapętla się przez linie wtemp1.txt
, ustawiając%%L
się na zawartość linii."delims="
to ciąg opcji, który określa, że wiersze nie powinny być dzielone na słowa. Umożliwia to działanie tego pliku wsadowego, nawet jeśli nazwy plików zawierają spacje.%%D
=Predator
) zewnętrznej pętli, kiedy robimy pierwszy przebieg (%%F
=Predator\Bear.txt
) drugiej pętli,temp1.txt
jest jak pokazano powyżej dlatemp2.txt
itemp2.txt
jest pusty.%%L
) fromtemp1.txt
,echo %%~nF_%%L >> temp2.txt
która zapisuje bieżącą nazwę pliku, znak podkreślenia_
i bieżącą linię (fromtemp1.txt
) dotemp2.txt
(dołączanie). Zatem po pierwszym przejściu (Bear
) drugiej pętli, zawierającej pełny przebieg trzeciej pętli,temp2.txt
będzie zawieraćCougar
Dołączone zostanie drugie przejście ( ) drugiej pętli dotemp2.txt
, i tak dalej.%%D
=Prey
) zewnętrznej pętli,temp1.txt
jesttemp2.txt
z poprzedniego przejścia, zawierającego dziewięć linii (z których sześć pokazano powyżej). Potem dzieje się to samo (z różnymi wartościami) jak poprzednio;%%F
ustawia się naPrey\Antelope.txt
, a więc każdy wiersztemp1.txt
jest kopiowanytemp2.txt
z wcześniej przygotowanymAntelope_
, i otrzymujemyfirst_pass
sięno
, usuń bieżącytemp1.txt
(jeśli w ogóle, a jeżeli jeszcze nie istnieje, tłumić komunikat o błędzie) i zmienić nazwętemp2.txt
natemp1.txt
.W rezultacie otrzymujemy plik o długości 27 linii (Num (
Habitat
) × Num (Predator
) × Num (Prey
)). Możesz dodawać i usuwać foldery i pliki, ponieważ w skrypcie nic nie jest zakodowane na stałe - nawet liczba folderów.Job_Titles
), Który nie zawiera plików, nie będzie danych wyjściowych (ponieważ 3 × 0 × 3 × 3 = 0). W rzeczywistości w tym przypadku powyższy plik wsadowy generuje wiele komunikatów o błędach oraz albo pustytemp1.txt
plik (oczekiwane zachowanie), albo w ogóle nie ma pliku. Można to oczywiście naprawić._
(podkreślenie). Na przykładAntelope_Mountain_Lion_Forest
jest niejednoznaczny.źródło
Możesz użyć PowerShell:
Po pierwsze, ten skrypt pobiera nazwy wszystkich kategorii (np. „Zdobycz”) i umieszcza je na
$categories
liście. Następnie definiuje funkcję rekurencyjną.AddCombos
pobiera wszystkie pliki w kategorii zindeksowane przez$catPos
. Jeśli nie ma go w ostatniej kategorii, wyświetla ukończony ciąg. W przeciwnym razie wywołuje się po dodaniu bieżącego elementu członkowskiego (np. „Jeleń”) do ciągu w toku i inkrementacji,$catPos
aby wskazać, że należy przejrzeć następną kategorię. Po zdefiniowaniu tej funkcji skrypt wywołuje ją od pierwszej kategorii (indeks 0) i z pustym ciągiem znaków w trakcie pracy.Pamiętaj, że kolejność kategorii jest ustalana alfabetycznie. Ponieważ nazwy folderów nie są używane w danych wyjściowych, możesz nazwać je w taki sposób, aby były tworzone w żądanej kolejności. Skrypt używa tytułów plików tekstowych w danych wyjściowych, ale jeśli chcesz kontrolować ich kolejność, zmieniając nazwy plików, możesz zmienić
$memberTitle =
wiersz na:To zajmuje pierwszy wiersz zawartości każdego pliku zamiast jego tytułu.
Ten skrypt może obsługiwać dowolną liczbę kategorii i dowolną liczbę członków w każdej kategorii.
Aby go uruchomić, zapisz go jako
.ps1
plik i postępuj zgodnie z instrukcjami w sekcji Włączanie skryptów wiki tagów PowerShell . Następnie możesz uruchomić go z pliku wsadowego takiego jak ten:źródło
Wygeneruje plik tymczasowy (do którego odwołuje się
%%t
), w którym konkatenuje linie wyjściowe.Dla każdego katalogu (
%%d
) plik tymczasowy jest odczytywany, czyszczony, a dla każdej linii (%%l
) w pliku tymczasowym jest ponownie powtarzany z każdym plikiem (%%f
) w bieżącym folderze połączonymPo połączeniu wszystkich nazw plików plik tymczasowy jest wysyłany do konsoli i usuwany.
źródło