2016-11-15 2 views
0

ich zur Zeit diese Zeile in einer Windows-Batch-Datei:Erhalten Sie alle Dateien von dir und alle subdirs außer einem subdir

@ REM List all *.f in current dir and all its subdirs 
dir *.f /B /S > temp1.txt 

Leider einer der subdirs (lass es pest nennen) hat einen sehr großen Teilbaum, was den Prozess ziemlich langsam macht. Da das Unterverzeichnis pest für diese spezielle Aufgabe eigentlich unwichtig ist (es sollte keine relevante Datei enthalten), möchte ich es von der Suche ausschließen.

Also, statt in aktuellen und allen Unterverzeichnissen zu suchen, würde ich in aktuellen dir und allen Unterverzeichnissen mit Ausnahme von pest suchen.

Können Sie einen einfachen Weg vorschlagen, dies zu tun?

+2

Die Ergebnisse des 'DIR'-Befehls an den' FIND'-Befehl übergeben und die/V-Option mit dem 'FIND'-Befehl verwenden. – Squashman

+1

@Squashman, dies verhindert nicht 'dir/S' von der Aufzählung des Verzeichnisses, was die Absicht der Frage ist, soweit ich es bekommen habe ... – aschipfl

Antwort

1

Wenn pest eine unmittelbare Unterverzeichnis des Stammes ist (dh das aktuelle Verzeichnis, .), könnten Sie wie folgt vorgehen:

rem // Enumerate immediate child files in the root, output them: 
> "temp1.txt" (for %%F in (".\*.f") do @echo %%~fF) 
rem // Enumerate immediate subdirectories of the root: 
>>"temp1.txt" (
    for /D %%D in (".\*.*") do @(
     rem // Skip the rest if current subdirectory is the one to exclude: 
     if /I not "%%~nxD"=="pest" (
      rem // Output all files found in the current subdirectory recursively: 
      pushd "%%~D" 
      for /R %%E in ("*.f") do @echo %%~E 
      popd 
     ) 
    ) 
) 

Das gibt nur Dateien, aber keine Verzeichnisse; wenn Sie so wollen, auch enthalten sein, versuchen Sie den folgenden Code ein:

rem // Output the path to the root directory itself: 
> "temp1.txt" (for /D %%D in (".") do @echo %%~fD) 
rem // Enumerate immediate child files in the root, output them: 
>>"temp1.txt" (for %%F in (".\*.f") do @echo %%~fF) 
rem // Enumerate immediate subdirectories of the root: 
>>"temp1.txt" (
    for /D %%D in (".\*.*") do @(
     rem // Skip the rest if current subdirectory is the one to exclude: 
     if /I not "%%~nxD"=="pest" (
      rem // Output the current subdirectory: 
      echo %%~fD 
      rem // Output all files found in the current subdirectory recursively: 
      for /F "eol=| delims=" %%E in ('dir /B /S "%%~D\*.f"') do @echo %%E 
     ) 
    ) 
) 

Wenn das pest Unterverzeichnis irgendwo im Baum sein kann, könnte man diesen Ansatz:

@echo off 
rem /* Call subroutine with the root directory (the current one), the file pattern 
rem and the name of the directory to exclude as arguments: */ 
> "temp1.txt" call :SUB "." "*.f" "pest" 
exit /B 

:SUB val_dir_path val_file_pattern val_dir_exclude 
rem // Output directory (optionally): 
echo %~f1 
rem // Enumerate immediate child files and output them: 
for %%F in ("%~1\%~2") do echo %%~fF 
rem // Enumerate immediate subdirectories: 
for /D %%D in ("%~1\*.*") do (
    rem // Skip the rest if current subdirectory is the one to exclude: 
    if /I not "%%~nxD"=="%~3" (
     rem /* Recursively call subroutine with the current subdirectory, the file pattern 
     rem and the name of the directory to exclude as arguments: */ 
     call :SUB "%%~D" "%~2" "%~3" 
    ) 
) 

Um zu vermeiden, Unterverzeichnisse, die ebenfalls ausgegeben werden, entfernen Sie einfach die Befehlszeile echo %~f1.

Da dieser Ansatz rekursive Subroutinenaufrufe unterstützt, ist die Leistung merklich schlechter als die Verwendung eines einfachen Befehls dir /S, falls kein Unterverzeichnis pest vorhanden ist.

+0

Danke. Deine erste Version macht genau das, was ich brauche. –

+0

Gern geschehen! Bitte beachten Sie, dass Sie die Antwort akzeptieren, indem Sie auf das grüne Häkchen klicken. Lesen Sie die folgenden Hilfethemen, um zu erfahren, was dies bedeutet und warum dies wichtig ist: [Was soll ich tun, wenn jemand meine Frage beantwortet?] (Was ist das, wenn ein Antwort ist "akzeptiert"?] (http://stackoverflow.com/help/accepted-answer) – aschipfl

0

Sie könnten möglicherweise das Verzeichnis Ausschluss Anlage in RoboCopy verwenden:

@Echo Off 

(Set SrcDir=C:\Users\Parker\Documents) 
(Set SrcMsk=*.f) 
(Set ToExcl=pest) 
(Set OutPut=temp1.txt) 

>"%OutPut%" (For /F "Tokens=*" %%A In ('RoboCopy "%SrcDir%" NULL %SrcMsk%^ 
/L /S /FP /NDL /NS /NC /NJH /NJS /XD "%ToExcl%"') Do Echo=%%A) 

Machen Sie Ihre relevanten Änderungen in den vier parenthesesed Zeilen wie nötig.

+0

Aus irgendeinem Grund gibt dies nicht nur * .f-Dateien zurück, sondern einfach alle? –

+0

Entschuldigung, es gibt einen Tippfehler in meiner Antwort _ (es heißt% ScrMsk% statt% SrcMsk%) _, jetzt behoben. – Compo

Verwandte Themen