Dateinamen aus Datei auslesen und kopieren
Hallo,
ich suche nach einem Batch, der folgendes macht:
1. Durchsuche alle .html-Dateien in einem Verzeichnis (dieses hat keine Unterverzeichnisse mehr) nach Pfadangaben zu einer pdf und einer dxf-Datei.
So eine Pfadangabe in einer .html-Datei sieht etwa so aus:
Also relative Pfadangaben.
2. Wenn Du alle Pfadangaben in jeder .html-Datei in diesem Verzeichnis gefunden hast, kopiere alle .pdf und .dxf-Dateien aus den gefundenen Pfadangaben in einen neuen Unterordner "Dokumente".
Alternativ kann das natürlich auch so ablaufen:
Wenn Du die erste Pfadangabe in der ersten .html-Datei gefunden hast, kopiere sofort die gefundene .pdf oder .dxf-Datei in einen neuen Unterordner "Dokumente" und suche dann nach der nächsten Pfadangabe, wenn Du keine mehr findest, nimm die nächste .html-Datei und suche dort etc, bis alle Dateien durchsucht und alle .pdf bzw. .dxf-Dateien kopiert sind.
3. Nett wäre noch ein log-file, woraus ersichtlich ist, welche Dateien erfolgreich kopiert wurden und wo es Probleme gab (zB weil die .pdf oder .dxf-Datei nicht existiert - sollte zwar nicht vorkommen, aber der Teufel schläft nicht...)
4. Ganz nett wäre noch eine Erklärung, wie das Ganze funktioniert
Ich hab zwar schon ähnliche Beiträge gefunden, blick da aber nicht durch (s. Punkt 4.) Wer kann mir da weiterhelfen?
ich suche nach einem Batch, der folgendes macht:
1. Durchsuche alle .html-Dateien in einem Verzeichnis (dieses hat keine Unterverzeichnisse mehr) nach Pfadangaben zu einer pdf und einer dxf-Datei.
So eine Pfadangabe in einer .html-Datei sieht etwa so aus:
<a href="../../pdf/web/7211.pdf">
2. Wenn Du alle Pfadangaben in jeder .html-Datei in diesem Verzeichnis gefunden hast, kopiere alle .pdf und .dxf-Dateien aus den gefundenen Pfadangaben in einen neuen Unterordner "Dokumente".
Alternativ kann das natürlich auch so ablaufen:
Wenn Du die erste Pfadangabe in der ersten .html-Datei gefunden hast, kopiere sofort die gefundene .pdf oder .dxf-Datei in einen neuen Unterordner "Dokumente" und suche dann nach der nächsten Pfadangabe, wenn Du keine mehr findest, nimm die nächste .html-Datei und suche dort etc, bis alle Dateien durchsucht und alle .pdf bzw. .dxf-Dateien kopiert sind.
3. Nett wäre noch ein log-file, woraus ersichtlich ist, welche Dateien erfolgreich kopiert wurden und wo es Probleme gab (zB weil die .pdf oder .dxf-Datei nicht existiert - sollte zwar nicht vorkommen, aber der Teufel schläft nicht...)
4. Ganz nett wäre noch eine Erklärung, wie das Ganze funktioniert
Ich hab zwar schon ähnliche Beiträge gefunden, blick da aber nicht durch (s. Punkt 4.) Wer kann mir da weiterhelfen?
Please also mark the comments that contributed to the solution of the article
Content-ID: 91346
Url: https://administrator.de/contentid/91346
Printed on: December 13, 2024 at 02:12 o'clock
24 Comments
Latest comment
Moin kristov,
nein, keine Lösung, sondern nur eine Nachfrage zur Wahl des richtigen Werkzeúgs:
als einziger "a href"-Tag in den HTMLs oder gibt es auch andere (auf *.jpg oder whatever), die Du aber nicht brauchst?
Grüße
Biber
nein, keine Lösung, sondern nur eine Nachfrage zur Wahl des richtigen Werkzeúgs:
- steht denn in den HTML-Dateien der Tag
<a href=,,[pdf oder dxf] >
- und stehen außer dem Tag noch andere Tags in der gleichen Zeile?
Grüße
Biber
Hallo kristov!
Doch, ein Ansatz einer Lösung:
Kurze Erklärung:
Nachdem der Zielordner (falls noch nicht vorhanden) erzeugt und die Log-Datei (falls bereits vorhanden) gelöscht wurde, erstellt der Batch ein VBScript.
In diesem wird in einer übergebenen Datei anhand "regulärer Ausdrücke" nach allen Textstücken gesucht, welche mit "<a href=" beginnen und mit ".pdf>" (mit oder ohne Anführungszeichen nach "pdf") bzw mit ".dxf>" enden. (Eine Plausibilitätsprüfung hinsichtlich der Länge des Links wäre sicher noch eine Überlegung wert ...)
Damit der gefundene Link brauchbar wird, erfolgt eine Zerlegung des Tags beim "=" und auch gleich eine Ersetzung von "/" durch "\" sowie ein Entfernen von Leerzeichen vor oder nach dem Link.
Das Script liefert zeilenweise je einen Link an den aufrufenden Batch zurück.
Im Batch dient die erste Schleife (%%a) der Behandlung aller .html-Dateien, die %%i-Schleife ruft das Script mit je einer dieser Dateien auf und erhält jeweils einzelne Links innerhalb von Anführungszeichen oder auch nicht, daher Weiterverarbeitung mit "%%~i" - jetzt ist der Link sicher durch Anführungszeichen begrenzt.
Danach wird kontrolliert, ob die verlinkte Datei vorhanden ist, und diese kopiert oder eine Fehlermeldung protokolliert. Beim Kopieren wird übrigens eine ev bereits vorhandene Datei im Ordner "Dokumente" überschrieben.
Abschließend wird, falls Dateien nicht gefunden wurden, die Liste dieser Dateien ausgegeben.
Anzumerken wäre, dass ein Link nach einem Zeilenumbruch oder etwa TAB zwischen "a href=" und dem Link derzeit nicht gefunden wird.
Grüße
bastla
Doch, ein Ansatz einer Lösung:
@echo off & setlocal
set "Basis=D:\test\files"
set "Typ=.html"
set "Ext=pdf|dxf"
set "Ziel=%Basis%\Dokumente"
set "Log=D:\Log.txt"
if not exist "%Ziel%" md "%Ziel%"
if exist "%Log%" del "%Log%"
set F=%temp%\FindLinks.vbs
> %F% echo T = CreateObject("Scripting.FileSystemObject").OpenTextFile(WScript.Arguments(0)).ReadAll
>> %F% echo Set R = New RegExp
>> %F% echo With R
>> %F% echo .Pattern = "<a href=.*\.(%Ext%)""?>"
>> %F% echo .IgnoreCase = True
>> %F% echo .Global = True
>> %F% echo Set Links = .Execute(T)
>> %F% echo End With
>> %F% echo For Each L In Links
>> %F% echo WScript.Echo Replace(Trim(Split(Left(L.Value, Len(L.Value) - 1), "=")(1)), "/", "\")
>> %F% echo Next
for %%a in ("%Basis%\*%Typ%") do (
for /f "delims=" %%i in ('cscript //nologo %F% %%a') do (
if exist "%Basis%\%%~i" (
copy "%Basis%\%%~i" "%Ziel%">nul
) else (
echo Nicht gefunden: "%Basis%\%%~i">>"%Log%"
)
)
)
if exist "%Log%" type "%Log%"
Nachdem der Zielordner (falls noch nicht vorhanden) erzeugt und die Log-Datei (falls bereits vorhanden) gelöscht wurde, erstellt der Batch ein VBScript.
In diesem wird in einer übergebenen Datei anhand "regulärer Ausdrücke" nach allen Textstücken gesucht, welche mit "<a href=" beginnen und mit ".pdf>" (mit oder ohne Anführungszeichen nach "pdf") bzw mit ".dxf>" enden. (Eine Plausibilitätsprüfung hinsichtlich der Länge des Links wäre sicher noch eine Überlegung wert ...)
Damit der gefundene Link brauchbar wird, erfolgt eine Zerlegung des Tags beim "=" und auch gleich eine Ersetzung von "/" durch "\" sowie ein Entfernen von Leerzeichen vor oder nach dem Link.
Das Script liefert zeilenweise je einen Link an den aufrufenden Batch zurück.
Im Batch dient die erste Schleife (%%a) der Behandlung aller .html-Dateien, die %%i-Schleife ruft das Script mit je einer dieser Dateien auf und erhält jeweils einzelne Links innerhalb von Anführungszeichen oder auch nicht, daher Weiterverarbeitung mit "%%~i" - jetzt ist der Link sicher durch Anführungszeichen begrenzt.
Danach wird kontrolliert, ob die verlinkte Datei vorhanden ist, und diese kopiert oder eine Fehlermeldung protokolliert. Beim Kopieren wird übrigens eine ev bereits vorhandene Datei im Ordner "Dokumente" überschrieben.
Abschließend wird, falls Dateien nicht gefunden wurden, die Liste dieser Dateien ausgegeben.
Anzumerken wäre, dass ein Link nach einem Zeilenumbruch oder etwa TAB zwischen "a href=" und dem Link derzeit nicht gefunden wird.
Grüße
bastla
Was ist »ein Batch«? Meinst Du ein Script für cmd.exe? Welches Betriebssystem, welche Version? Suchst Du eine Lösung für Dein Problem oder eine Lösung für die Aufgabenstellung?
0.
Start->Run->cmd
1.
help for
help set
help if
google »cmd redirection«
2.
help copy
3.
google »cmd redirection«
4.
Das Ganze funktioniert (abgesehen von der üblichen noch notwendigen Popelei) bestenfalls zufällig: Es ist kaum annehmbar, daß die Anker an fixen Stellen in den HTML-Dateien stehen, genau ein HTML-Tag pro Zeile, und das Tag nie auf mehrere Zeilen verteilt. In einem nullten Durchgang müßten diese Vorraussetzungen vorbereitet werden. Ein Cmd-Script ist dafür ein masochistischer Lösungsansatz.
0.
Start->Run->cmd
1.
help for
help set
help if
google »cmd redirection«
2.
help copy
3.
google »cmd redirection«
::REM Name der logdatei
set log=%~n0.log.txt
::REM Verzeichnis Dokumente erstellen und log initialisieren.
mkdir Dokumente >%log%
::REM alle Dateien *html zeilenweise einlesen; an den Trennzeichen <, =, > in Tokens splitten.
::REM Das erste Token sei Variable %a; das zweite Token wird dann %b: der relative Pfad (inkl. ").
::REM Wegen Verwendung im Script ist dem Variablennamen ein weiteres % voranzustellen: %%a,...
::REM Wenn Token 1 ein »a href« ist, in die Bearbeitung einsteigen ...
::REM Wenn die Extension von %b dxf oder pdf ist, Datei nach Ordner Dokumente kopieren.
for /F "tokens=1,2 delims=<=>" %%a in (*.html) do if "%%a"=="a href" (
echo %%b >>%log%
if "%%~xb"=="dxf" copy /y %%b Dokumente >>%log%
if "%%~xb"=="pdf" copy /y %%b Dokumente >>%log%
)
4.
Das Ganze funktioniert (abgesehen von der üblichen noch notwendigen Popelei) bestenfalls zufällig: Es ist kaum annehmbar, daß die Anker an fixen Stellen in den HTML-Dateien stehen, genau ein HTML-Tag pro Zeile, und das Tag nie auf mehrere Zeilen verteilt. In einem nullten Durchgang müßten diese Vorraussetzungen vorbereitet werden. Ein Cmd-Script ist dafür ein masochistischer Lösungsansatz.
Hallo 1bgks6 und willkommen im Forum!
Einige Anmerkungen zu
Da "%%~xb" als Ergebnis zB ".dxf" liefert, gehört der Punkt auch in den Vergleichswert.
Mit "if /i" kannst Du dafür sorgen, dass auch ".DXF"-Dateien kopiert werden.
Ein "copy" in einem Batch kommt ohne "/y" aus.
Der durch ">>%log%" erzeugte Eintrag "1 Datei(en) kopiert." ist zwar informativ, aber vielleicht doch besser mit der vorhergehenden Zeile zu kombinieren - etwa:
Grüße
bastla
Ein Cmd-Script ist dafür ein masochistischer Lösungsansatz.
"Masochistisch" ist vielleicht etwas übertrieben, aber mühsam ist es sicher ...Einige Anmerkungen zu
if "%%~xb"=="dxf" copy /y %%b Dokumente >>%log%
Mit "if /i" kannst Du dafür sorgen, dass auch ".DXF"-Dateien kopiert werden.
Ein "copy" in einem Batch kommt ohne "/y" aus.
Der durch ">>%log%" erzeugte Eintrag "1 Datei(en) kopiert." ist zwar informativ, aber vielleicht doch besser mit der vorhergehenden Zeile zu kombinieren - etwa:
if /i "%%~xb"==".dxf" copy "%%~b" Dokumente && echo Kopiert: "%%~b">>"%log%"
bastla
Moin kristov,
schau mal bitte nach, auf welches Verzeichnis Deine %temp%-Variable zeigt.
Wahrscheinlich kommt bei heraus:
... also ein Pfad mit Leerzeichen im Namen.
In diesem Fall solltest Du diese %F%-Variable ebenfalls in Anführungszeichen setzen. Also bastlas Zeilen 12/13 anpassen:
[rein biooptische Kurzanalyse, nicht getestet]
Grüße
Biber
schau mal bitte nach, auf welches Verzeichnis Deine %temp%-Variable zeigt.
Wahrscheinlich kommt bei heraus:
>set temp
TEMP=C:\Dokumente und Einstellungen\kristov\Lokaler Firlefanz\Temp
In diesem Fall solltest Du diese %F%-Variable ebenfalls in Anführungszeichen setzen. Also bastlas Zeilen 12/13 anpassen:
...
set F="%temp%\FindLinks.vbs"
> %F% echo T = CreateObject
...
[rein biooptische Kurzanalyse, nicht getestet]
Grüße
Biber
Hallo kristov und Biber, bin wieder da ...
Um dem Problem auf die Spur zu kommen, bitte einmal in Zeile 24 ein "echo on" einfügen und in der entstehenden Ausgabe den Dateinamen/-pfad hinter
überprüfen.
Grüße
bastla
... auf welches Verzeichnis Deine %temp%-Variable zeigt.
... sollte als Fehlerquelle auszuschließen sein, da für %TEMP% der Kurzname verwendet werden sollte und daher das Leerzeichen nicht zum Tragen käme - Anführungszeichen schaden aber natürlich nicht. Werd mir das CreateObject genau zerlegen und durchprüfen müssen, was das genau macht
Der gesamte in der als Parameter übergebenen Datei (wenn denn eine übergeben wird, siehe unten) enthaltene Text wird für die Linksuche durch diese Zeile in eine Variable (T) eingelesen. (Das einfache ">" ist übrigens Absicht - damit wird sicher gestellt, dass das Script immer neu erzeugt wird, da die erste "echo"-Zeile so eine alte Version überschreibt.)und ob die Syntax so stimmt...
Der Fehlermeldung nach liegt das Problem darin, dass das Script ohne Übergabe eines Argumentes (geöffnet/gelesen werden soll ja die Datei in WScript.Arguments(0)) aufgerufen wird - was eigentlich, obwohl ich in Zeile 26 die Anführungszeichen um das "%%a" herum vergessen habe, gar nicht möglich sein sollte - wenn %%a leer wäre, dürfte ja das "do" der "for"-Schleife nicht ausgeführt werden, und wenn es passende (.html-) Dateien mit einem Leerzeichen im Namen gibt, wäre die VBScript-Fehlermeldung "Die Datei wurde nicht gefunden." ...Um dem Problem auf die Spur zu kommen, bitte einmal in Zeile 24 ein "echo on" einfügen und in der entstehenden Ausgabe den Dateinamen/-pfad hinter
... cscript //nologo C:\DOKUME~1\kristov\LOKALE~1\Temp\FindLinks.vbs
Grüße
bastla
Hallo kristov!
Wie oben schon angemerkt, muss zur Sicherheit in Zeile 26 auch "%%a" unter Anführungszeichen stehen, also:
Allerdings weist Deine Ausgabe darauf hin, dass überhaupt keine .html-Datei gefunden wird - gesucht wird nämlich nur im %Basis%-Verzeichnis. Je nachdem, wo das neue "Dokumente"-Verzeichnis hin soll, ist daher entweder der Basis-Pfad oder in Zeile 25 das zu durchsuchende Verzeichnis anzupassen ...
Grüße
bastla
Wie oben schon angemerkt, muss zur Sicherheit in Zeile 26 auch "%%a" unter Anführungszeichen stehen, also:
for /f "delims=" %%i in ('cscript //nologo %F% "%%a"') do (
Allerdings weist Deine Ausgabe darauf hin, dass überhaupt keine .html-Datei gefunden wird - gesucht wird nämlich nur im %Basis%-Verzeichnis. Je nachdem, wo das neue "Dokumente"-Verzeichnis hin soll, ist daher entweder der Basis-Pfad oder in Zeile 25 das zu durchsuchende Verzeichnis anzupassen ...
Grüße
bastla
Hallo kristov!
Wie sieht denn die nächste Ausgabezeile aus (hier sollte ja "%~i" durch den extrahierten Pfad ersetzt werden)?
Du kannst testweise auch einmal an der Kommandozeile eingeben (oder auch per Drag and Drop der .html-Datei auf die .vbs-Datei testen):
Das Ergebnis müsste der durch das VBScript extrahierte Linkpfad sein.
Grüße
bastla
Könnte es sein, daß er mit der Kombination aus der %Basis% und der %%i nicht zurecht kommt (Mischung aus absolutem und relativem Pfad?).
Das sollte kein Problem sein.Wie sieht denn die nächste Ausgabezeile aus (hier sollte ja "%~i" durch den extrahierten Pfad ersetzt werden)?
Du kannst testweise auch einmal an der Kommandozeile eingeben (oder auch per Drag and Drop der .html-Datei auf die .vbs-Datei testen):
cscript //nologo "C:\DOKUME~1\cwimmer\LOKALE~1\Temp\FindLinks.vbs" "N:\html\z0302_03\html\z0318AA-06.html"
Grüße
bastla
Hallo Kristov!
Bei mir sieht das so aus (ich habe einfach den Punkt 1 Deines Beitrages als "D:\Test\files\Eine Datei.html" gespeichert):
Wie es aussieht, kann das Script die Links in Deinen Dateien nicht finden. Könntest Du eine Originaldatei posten (oder auch mailen)?
Grüße
bastla
Bei mir sieht das so aus (ich habe einfach den Punkt 1 Deines Beitrages als "D:\Test\files\Eine Datei.html" gespeichert):
D:\>type "%temp%\FindLinks.vbs"
T = CreateObject("Scripting.FileSystemObject").OpenTextFile(WScript.Arguments(0)
).ReadAll
Set R = New RegExp
With R
.Pattern = "<a href=.*\.(pdf|dxf)""?>"
.IgnoreCase = True
.Global = True
Set Links = .Execute(T)
End With
For Each L In Links
WScript.Echo Replace(Trim(Split(Left(L.Value, Len(L.Value) - 1), "=")(1)), "
/", "\")
Next
D:\>type "D:\Test\files\Eine Datei.html"
1. Durchsuche alle .html-Dateien in einem Verzeichnis (dieses hat keine Unterver
zeichnisse mehr) nach Pfadangaben zu einer pdf und einer dxf-Datei.
So eine Pfadangabe in einer .html-Datei sieht etwa so aus: <a href="../../pdf/we
b/7211.pdf">, also relative Pfadangaben.
D:\>cscript "%temp%\FindLinks.vbs" "D:\Test\files\Eine Datei.html"
"..\..\pdf\web\7211.pdf"
D:\>
Grüße
bastla