So durchlaufen Sie Dateien, die mit dem Platzhalter in der Batchdatei übereinstimmen


193

Ich habe eine Reihe von Basisdateinamen, für jeden Namen 'f' gibt es genau zwei Dateien, 'f.in' und 'f.out'. Ich möchte eine Batch-Datei (in Windows XP) schreiben, die alle Dateinamen durchläuft, für jeden sollte es:

  • Zeigen Sie den Basisnamen 'f' an.
  • Führen Sie eine Aktion für 'f.in' aus.
  • Führen Sie eine weitere Aktion für 'f.out' aus.

Ich habe keine andere Möglichkeit, die Basisdateinamen aufzulisten, als beispielsweise nach * .in (oder * .out) zu suchen.


10
Ich möchte wirklich nicht dieser Typ nach 111/0 Stimmen sein, aber Ihre Frage zeigt keine Forschung überhaupt
phil294

Antworten:


292

Angenommen, Sie haben zwei Programme, die die beiden Dateien verarbeiten, process_in.exe und process_out.exe:

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

%% ~ nf ist ein Substitutionsmodifikator, der% f nur auf einen Dateinamen erweitert. Weitere Modifikatoren finden Sie unter https://technet.microsoft.com/en-us/library/bb490909.aspx (in der Mitte der Seite) oder einfach in der nächsten Antwort.


47
Verwenden Sie ein einzelnes '%', wenn Sie dies in der Befehlszeile eingeben. Ich weiß, dass das OP nicht nach der Befehlszeile fragt, aber danach habe ich gesucht, als diese Frage oben in meiner Google-Suche auftauchte. Andere mögen dieses bisschen zu schätzen wissen.
Jason

2
Könnten Sie die Syntax erklären? Die Schleifenvariable wird deklariert, %%fwarum ist es %%~nfspäter?
Colonel Panic

6
@ColonelPanic - Es gibt eine Handvoll ~Modifikatoren, um Dinge zu tun, wie in meinem Beispiel, nur den Dateinamen abrufen. Es ist nur eine Gewohnheit für mich, das zu benutzen, falls der *den vollen Weg macht oder so. Es gibt eine Handvoll dieser Modifikatoren (in der Mitte der Seite): microsoft.com/resources/documentation/windows/xp/all/proddocs/…
Jim Buck

Was ist, wenn die Datei und das Verzeichnis Leerzeichen enthalten?
BKSpurgeon

3
Beachten Sie außerdem, dass die Variable %% f aus einem einzelnen Buchstaben bestehen muss. Wenn Sie versuchen, etwas Lesbares und Sinnvolles zu verwenden, werden kryptische Fehlermeldungen angezeigt.
Bruce Dawson

90

Mit dieser Zeile können Sie den Inhalt Ihres Desktops drucken:

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

Sobald Sie die %%IVariable haben, ist es einfach, einen Befehl darauf auszuführen (ersetzen Sie einfach das Wort Echo durch Ihr Programm).

Darüber hinaus wurde die Ersetzung von FOR-Variablenreferenzen verbessert. Sie können jetzt die folgende optionale Syntax verwenden:

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

In den obigen Beispielen %Ikann PATH durch andere gültige Werte ersetzt werden. Die %~Syntax wird durch einen gültigen FOR-Variablennamen beendet. Wenn Sie Variablennamen in Großbuchstaben wie %Iauswählen, wird die Lesbarkeit verbessert und Verwechslungen mit den Modifikatoren vermieden, bei denen die Groß- und Kleinschreibung nicht berücksichtigt wird.

Sie können die vollständige Dokumentation durch Eingabe erhalten FOR /?


Das scheint nicht zu funktionieren. %%I was unexpected at this time.
Brad

4
@Brad, wenn Sie dies in der Befehlszeile (und nicht in einer Batch-Datei) verwenden, dann verwenden Sie %Ianstelle von%%I
doubleDown

1
Eine viel bessere Antwort als die akzeptierte. Alle Flags / Modifikatoren in der Antwort enthalten und keine Website eines Drittanbieters ( niemand möchte auf Ihren Link klicken, Louis )
JustCarty

5

Aus meiner Sicht ist es am einfachsten, eine for-Schleife zu verwenden, die eine zweite Batchdatei zur Verarbeitung aufruft und dieser zweiten Datei den Basisnamen übergibt.

Nach dem für /? Hilfe, Basisname kann mit der Option nifty ~ n extrahiert werden. Das Basisskript würde also lauten:

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

Nehmen Sie dann in process.cmd an, dass% 0 den Basisnamen enthält, und handeln Sie entsprechend. Beispielsweise:

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

Es gibt vielleicht einen besseren Weg, dies in einem Skript zu tun, aber ich war immer ein bisschen verschwommen, wie man mehrere Befehle in einer einzigen for-Schleife in einer Batch-Datei abruft.

EDIT: Das ist fantastisch! Ich hatte irgendwie die Seite in den Dokumenten verpasst, die zeigte, dass Sie mehrzeilige Blöcke in einer FOR-Schleife ausführen können. Ich werde jetzt zurückgehen und einige Batch-Dateien neu schreiben müssen ...


4

Aufbauend auf Nathans Post. Im Folgenden wird das Auftragslos in einer Batchdatei ausgeführt.

@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

3

Es gibt ein Tool, das normalerweise in MS-Servern verwendet wird (soweit ich mich erinnern kann) und forfiles heißt :

Der obige Link enthält Hilfe sowie einen Link zur Microsoft-Downloadseite.


1

Der folgende Code filtert Dateinamen, die mit der angegebenen Teilzeichenfolge beginnen. Es kann geändert werden, um verschiedenen Anforderungen zu entsprechen, indem an der Subnamen-Teilstring-Extraktion und der IF-Anweisung gearbeitet wird:

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

0

Wenn Sie f.in und f.out wiederholen, wird das Konzept getrennt, was in einer for / f-Schleife wiederholt werden soll und was nicht.

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

Obwohl Sie nicht gefragt haben, wäre eine gute Möglichkeit, Befehle an f.in und f.out zu übergeben, ...

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

Ein Link zu allen Windows XP-Befehlen: Link

Ich entschuldige mich, wenn ich dies nicht richtig beantwortet habe. Die Frage war für mich sehr schwer zu lesen.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.