whine: batch Ordner vergleichen

Guten Morgen! Ich habe ein Verzeichnis mit ein paar hundert .eps Dateien und ein weiteres mit diesen als .svg abgespeichert. Nun fehlen einige Hände voll .svg Dateien, die ich herausfinden möchte. Der Dateiname ist immer gleich, nur die Extension ist unterschiedlich.

Mit diesem Script werden mir fehlenden Dateien in einen /result-Ordner gespeichert. Leider nur, wenn ich das Beispieldateien bei gleicher Extension ausprobiere.

@echo off &setlocal
set /p "svg=Verzeichnis svg: "
set /p "eps=Verzeichnis eps: "
set /p "result=Verzeichnis result: "

if not exist "%svg%" (echo Ordner svg ist nicht vorhanden! &pause>nul &goto :eof)
if not exist "%eps%" (echo Ordner eps ist nicht vorhanden! &pause>nul &goto :eof)
md "%result%" 2>nul
for /f "delims=" %%a in ('dir /a-d /b "%eps%\*.*"') do (
  if not exist "%svg%\%%~a" copy "%eps%\%%~a" "%result%\%%~a"
)
pause

Wie bekomme ich das hin, dass er er mir nur den Dateinamen ohne Extension prüft, also

test1.eps versus test1.svg --> Datei ist da, keine Aktion

test55.eps --> keine test55.svg gefunden --> speichern von test55.eps in /result

Hat jemand eine Idee?

whine

  1. Hallo whine,

    eigentlich hast Du alle Bausteine.

    Mit ein paar Ergänzungen:

    1. for /f "delims=" %%a in ('dir /a-d /b "%eps%\*.*"')

    Dieser Befehl ruft DIR auf, um eine Verzeichnisliste zu erstellen, und interpretiert dann die Ausgabe von DIR. Das ist aber von hinten durch die Brust ins Auge, sowas kann FOR ganz alleine. Es ist dann auch hilfreich, die Suche auf Dateien mit eps-Extension zu begrenzen.

    So geht's: FOR %%a in ("%eps%\*.eps") DO ...

    %%a enthält nun nacheinander die EPS-Dateinamen, inclusive Pfad.

    Beachte, dass FOR /F %%a IN ("*.eps") DO etwas ganz anderes ist als FOR %%a in ("*.eps") DO. Die /F Option bewirkt, dass Datein nicht aufgelistet werden, sondern ihr Inhalt eingelesen, und wenn dann die IN Angabe in "Anführungszeichen" steht, wird sie nicht als Dateiname sondern als einfacher Text interpretiert. Steht sie in 'einfachen' Anführungszeichen, wird sie als CMD-Befehl interpretiert, dessen Standardausgabe dann gelesen wird. Ohne Anführungszeichen wird ein Dateiname (ohne Muster) erwartet.

    Ohne /F muss die IN Angabe ein oder mehrere Dateimuster enthalten, und dann dienen die doppelten Anführungszeichen dazu, Leerstellen in Dateinamen darstellen zu können. FOR %%a IN (a1.eps a2.eps) verarbeitet zwei Dateien. FOR %%a IN ("a1.eps a2.eps") verarbeitet eine Datei mit Namen "a1.eps a2.eps".

    Eine Anleitung zum FOR Befehl bekommst Du auf der Windows Befehlszeile mit HELP FOR, oder hier. Vergiss die deutsche Version, die scheint maschinell übersetzt.

    1. Zerlegen von Dateinamen

    Da hast Du schon den richtigen Ansatz, aber %%~a ist unvollständig. Wenn %%a ein for-Parameter ist, dann aktiviert %%~a die Zerlegungsoptionen, aber ohne weitere Parameter entfernt es nur eventuell vorhandene Anführungszeichen. Das ist bei FOR überflüssig weil da nie Anführungszeichen kommen.

    Was Du brauchst, ist %%~na. n steht für Name. Entscheidend ist, dass da kein p (für Pfad) und kein x (für eXtension) steht. Aus C:\EPS_FILES\FOO.EPS wird mit diesen Modifiziereren FOO, und da musst Du für den EXIST Test nur noch .svg dahinterschreiben.

    FOR %%a in ("%eps%\*.eps") do (
       IF NOT EXIST "%svg%\%%~na.svg" COPY "%%a" "%result%"
    )
    

    (Edit: fehlendes Anführungszeichen ergänzt)

    Der FOR Befehl ist ein extrem zickiges Biest, ich weiß. Und er ist seit seine Erfindung in frühen MS DOS Versionen nur zickiger geworden. Allein schon die doppelten Anführungszeichen für die FOR Variable sind nervig, aber das ist der CMD Syntax geschuldet, die Variablen mit einfachen % schon auflöst bevor der ausgeführte Befehl die Variable auch nur zu sehen bekommt. Man schreibt %%, weil das der CMD-Weg ist um die Variablenauflösung zu umgehen und ein einzelnes % zu bekommen. Und dieses wird dann vom FOR Befehl als Parameter-Marker verwendet. Deswegen schreibt man, wenn man FOR von Hand auf der Befehlszeile ausführt, FOR %a IN (...) DO statt FOR %%a IN (...). Aber wer macht sowas schon außer ein paar Hardcore-Batchern aus den 80er Jahren 😂

    Die Alternative zu CMD ist Powershell, aber da hat man eine noch steilere Lernkurve als bei CMD zu erklimmen...

    Rolf

    --
    sumpsi - posui - obstruxi
    1. Hallo Rolf,

      vielen Dank für die ausführliche Erklärung. Ich sehe schon, wenn ich mer in die Richtung machen will, muss ich whl doch noch einiges investieren.

      Auf jeden Fall hilft deine Antwort zur Lösung meines Problems. Ein kleiner Schönheistfehler war noch:

      FOR %%a in ("%eps%\*.eps") do (
         IF NOT EXIST "%svg%\%%~na.svg" COPY "%%a" "%result%"
      )
      

      Hinter svg fehlte ein Anführungszeichen.

      Vielen Dank nochmal und schönes WE! whine

      1. Hallo whine,

        ich mache das seit 35 Jahren, so langsam geht's ;)

        Aber im Alter fallen einem schon Mal die Anführungszeichen aus den zittrigen Fingern, sorry.

        Rolf

        --
        sumpsi - posui - obstruxi