Jak przeglądać pliki pasujące do znaku wieloznacznego w pliku wsadowym

193

Mam zestaw podstawowych nazw plików, dla każdej nazwy „f” są dokładnie dwa pliki, „f.in” i „f.out”. Chcę napisać plik wsadowy (w systemie Windows XP), który przechodzi przez wszystkie nazwy plików, dla każdego powinien:

  • Wyświetl nazwę podstawową „f”
  • Wykonaj akcję na „f.in”
  • Wykonaj kolejną akcję na „f.out”

Nie mam sposobu, aby wyświetlić zestaw podstawowych nazw plików, poza tym, że na przykład mogę wyszukać * .in (lub * .out).

Luke Halliwell
źródło
10
Naprawdę nie chcę być tym facetem po 111/0 głosach, ale twoje pytanie nie pokazuje żadnego reasearcha whatsoeaver
phil294 24.04.2016

Odpowiedzi:

292

Zakładając, że masz dwa programy przetwarzające dwa pliki, process_in.exe i process_out.exe:

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

%% ~ nf to modyfikator podstawiania, który rozwija% f tylko do nazwy pliku. Zobacz inne modyfikatory w https://technet.microsoft.com/en-us/library/bb490909.aspx (w połowie strony) lub tylko w następnej odpowiedzi.

Jim Buck
źródło
47
Użyj pojedynczego „%”, wpisując to w wierszu polecenia. Wiem, że OP nie pyta o wiersz poleceń, ale tego właśnie szukałem, kiedy to pytanie pojawiło się na górze mojej wyszukiwarki Google. Inni mogą to docenić.
Jason
2
Czy możesz wyjaśnić składnię? Zmienna pętli jest deklarowana, %%fdlaczego jest %%~nfpóźniej?
Pułkownik Panic
6
@ColonelPanic - jest kilka ~modyfikatorów do robienia rzeczy, tak jak w moim przykładzie, po prostu pobierz nazwę pliku. Po prostu używam tego na wypadek, gdyby *wykonał pełną ścieżkę czy coś takiego. Istnieje kilka takich modyfikatorów (w połowie strony): microsoft.com/resources/documentation/windows/xp/all/proddocs/…
Jim Buck
co jeśli plik i katalog mają spacje?
BKSpurgeon
3
Pamiętaj również, że zmienna %% f musi być pojedynczą literą - jeśli spróbujesz użyć czegoś czytelnego i znaczącego, pojawią się tajemnicze komunikaty o błędach.
Bruce Dawson
90

Możesz użyć tego wiersza, aby wydrukować zawartość pulpitu:

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

Gdy masz już %%Izmienną, łatwo jest na niej wykonać polecenie (po prostu zamień słowo echo w programie)

Ponadto ulepszono podstawianie odwołań do zmiennych FOR Można teraz użyć następującej opcjonalnej składni:

%~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

W powyższych przykładach %Ii PATH można zastąpić innymi prawidłowymi wartościami. %~Składnia jest zakończony poprawną nazwą zmiennej FOR. Wybór nazw zmiennych, takich jak%I czyni go bardziej czytelnym i pozwala uniknąć pomyłek z modyfikatorami, które nie rozróżniają wielkości liter.

Możesz uzyskać pełną dokumentację, pisząc FOR /?

Mark Ingram
źródło
To nie działa. %%I was unexpected at this time.
Brad
4
@Brad, jeśli używasz tego w wierszu polecenia (a nie w pliku wsadowym), użyj %Izamiast%%I
doubleDown
1
O wiele lepsza odpowiedź niż zaakceptowana. Wszystkie flagi / modyfikatory zawarte w odpowiedzi, a nie strona internetowa strony trzeciej ( nikt nie chce kliknąć twojego linku, Louis )
JustCarty 24.04.2018
5

Najprostszym sposobem, jak widzę, jest użycie pętli for, która wywołuje drugi plik wsadowy do przetworzenia, przekazując temu drugiemu plikowi nazwę podstawową.

Według for /? help, basename można wyodrębnić za pomocą opcji nifty ~ n. Tak więc skrypt podstawowy brzmiałby:

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

Następnie, w process.cmd, załóż, że% 0 zawiera nazwę podstawową i działaj odpowiednio. Na przykład:

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

Może być lepszy sposób na zrobienie tego w jednym skrypcie, ale zawsze byłem trochę zamglony, jak wyciągać wiele poleceń w jednej pętli for w pliku wsadowym.

EDYCJA: To fantastycznie! Jakoś przegapiłem stronę w dokumentach, która pokazała, że ​​możesz robić wieloliniowe bloki w pętli FOR. Mam zamiar teraz wrócić i przepisać niektóre pliki wsadowe ...

Nathan Fritz
źródło
4

Rozwijanie postu Nathans . Poniższe czynności wykonają partię zadania w jednym pliku wsadowym.

@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
Jaskółka oknówka
źródło
3

Istnieje narzędzie zwykle używane w MS Server (o ile pamiętam) o nazwie forfiles :

Powyższy link zawiera pomoc oraz link do strony pobierania Microsoft.


źródło
1

Poniższy kod filtruje nazwy plików zaczynające się od podanego podłańcucha. Można to zmienić, aby dopasować do różnych potrzeb, pracując nad ekstrakcją podfazów i instrukcją 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
Sandro Rosa
źródło
0

Wyszukanie f.in i f.out rozdzieli koncepcję tego, co należy zapętlić, a czego nie zapętlić, gdy jest używane w pętli for / f.

::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
)

Chociaż nie pytałeś, dobrym sposobem na przekazywanie poleceń do f.in i f.out byłoby ...

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

Link do wszystkich poleceń systemu Windows XP: link

Przepraszam, jeśli nie odpowiedziałem poprawnie. Pytanie było dla mnie bardzo trudne do odczytania.

Z. Mickaels
źródło