Grössere Menge pdfs überprüfen

Moien

ein Kumpel hat mir 25.000 (!) Pdf-Dateien auf einer externen Platte übergeben. Die Platte hat einen Hau weg und liefert teilweise Müll beim auslesen. D.h. man müsste jetzt alle Dateien einzeln öffnen und zumindest die die nicht mehr laden aussortieren.

Wie macht man sowas möglichst automatisch?

Danke

ein Kumpel hat mir 25.000 (!) Pdf-Dateien auf einer externen
Platte übergeben. Die Platte hat einen Hau weg und liefert
teilweise Müll beim auslesen. D.h. man müsste jetzt alle
Dateien einzeln öffnen und zumindest die die nicht mehr laden
aussortieren.

Ich würd einfach ein Bash-Skript schreiben.
Dieses soll mit pdf2ps versuchen die PDFs in Postscript-Files umzuwandeln. Da kannst ja als Ausgabedatei /dev/null nehmen. Wenn das fehlschlägt, sollte das pdf2ps normal ja irgendwas ungleich 0 zurück geben. Der Rückgabewert lässt sich nach Ausführung des Befehls mit der Variable $? auslesen.

Ist der Rückgabe-Wert 0, dann ist die Datei OK.
Ist der Rückgabewert != 0 dann ist die Datei möglicherweise defekt.

Möglicherweise deswegen, weil ps2pdf mit manchen regulären PDFs auch Probleme hat. Aber die als Defekt markierten PDFs sind ja dann wohl nicht so viele, die kann man dann ja vielleicht auch händisch überprüfen.

Hallo deconstruct,

Ich würd einfach ein Bash-Skript schreiben.
Dieses soll mit pdf2ps versuchen die PDFs in Postscript-Files
umzuwandeln. Da kannst ja als Ausgabedatei /dev/null nehmen.
Wenn das fehlschlägt, sollte das pdf2ps normal ja irgendwas
ungleich 0 zurück geben.

Gute Idee, scheint aber nicht (immer?) zu funktionieren. Ich habe mal ein pdf-File von Hand zerstört und deinen Vorschlag ausprobiert. Hier das Ergebnis:

ubuntu@ubuntu:~$ pdf2ps Desktop/msg00095.pdf 
 \*\*\*\* Warning: An error occurred while reading an XREF table.
 \*\*\*\* The file has been damaged. This may have been caused
 \*\*\*\* by a problem while converting or transfering the file.
 \*\*\*\* Ghostscript will attempt to recover the data.

 \*\*\*\* This file had errors that were repaired or ignored.
 \*\*\*\* The file was produced by: 
 \*\*\*\* \>\>\>\> htmldoc 1.8.23 Copyright 1997-2002 Easy Software Products, All Rights Reserved. 
Wenn ich jetzt auf die Schnelle keinen Denkfehler mache, sollte man also nicht den Rückgabewert untersuchen, sondern die Fehlermeldung von pdf2ps.

Viele Grüße
Marvin

This file had errors that were repaired or ignored.
**** The file was produced by:

Ich weiß nicht, wie stark und wie du das PDF beschädigt hast. Offenbar war der Schaden nicht so groß, dass Postscript den Fehler nicht beheben oder ignorieren konnte und dennoch eine Konvertierung durchführen konnte.
Solche Fehler haben oftmals viele PDFs, nicht aufgrund von Beschädigung sondern wegen fehlerhafter Erstellung durch die Software, mit der das PDF erzeugt wurde. Das ist daher teilweise normal. Da pdf2ps eine Konvertierung trotz des Fehlers durchführen konnte, hat es daher 0 zurück gegeben.

Wenn ich jetzt auf die Schnelle keinen Denkfehler mache,
sollte man also nicht den Rückgabewert untersuchen, sondern
die Fehlermeldung von pdf2ps.

Naja, man sollte schon in erster Linie den Rückgabe-Wert untersuchen. Wenn ein gravierender Fehler auftritt, und die Konvertierung komplett scheitert, dann gibt pdf2ps einen Wert ungleich 0 zurück. Dann ist die Datei mit großer Wahrscheinlichkeit wirklich beschädigt.

Folgendes Beispiel, in der ein korrektes PDFs zu einer ähnlichen Fehlermeldung führt:
Man lade sich diesen schönen Gesetzesbeschluss zur Neuregelung der Telekommunikationsüberwachung herunter:
http://dip21.bundestag.de/dip21/brd/2007/0798-07.pdf
Obwohl die Datei lustigerweise mit Adobe Acrobat 6.0 erstellt wurde, entspricht sie nicht der von Adobe selbst erstellten PDF-Spezifikation :wink: Dadurch erhält man eine ähnliche Fehlermeldung, wie in deinem Beispiel. Wir werden die Datei „kaputt“ machen, in dem wir simulieren, dass das Dateiende verloren gegangen ist (z.B. durch Dateisystem-Fehler oder Übetragungsfehler).

1. Laden des PDF-Files und abspeichern unter „korrekt.pdf“.

$\> wget http://dip21.bundestag.de/dip21/brd/2007/0798-07.pdf -O korrekt.pdf
11:18:43 (225.26 KB/s) - »korrekt.pdf« gespeichert [128792/128792]

2. „Kaputtmachen“ mit dd:
Einfach nur die ersten 51200 Bytes der Datei in neue Datei kaputt.pdf speichern um Übertragungsabbruch zu simulieren. Danach hat man zwei Files korrekt.pdf und kaputt.pdf:

$\> dd bs=512 count=100 if=korrekt.pdf of=kaputt.pdf
100+0 Datensätze ein
100+0 Datensätze aus
51200 Bytes (51 kB) kopiert, 0,000503099 s, 102 MB/s

$\> ls -l
insgesamt 188
-rw-r--r-- 1 dellwo dellwo 51200 2008-11-16 11:19 kaputt.pdf
-rw-r--r-- 1 dellwo dellwo 128792 2007-11-12 15:50 korrekt.pdf

3. Umwandeln des korrekten PDFs:
pdf2ps gibt zwar Warnungen aus, aber konvertiert das PDF und gibt daher 0 zurück.

$\> pdf2ps korrekt.pdf 

 \*\*\*\* Warning: Fonts with Subtype = /TrueType should be embedded.
 The following fonts were not embedded:
 Arial-BoldMT
 ....

 \*\*\*\* This file had errors that were repaired or ignored.
 \*\*\*\* The file was <u>produced by</u>: 
 \*\*\*\* \>\>\>\> <u>Adobe Acrobat</u> 6.0 does not conform to Adobe's published PDF
 \*\*\*\* <u>specification.</u>

$\> echo $?
0

4. Umwandeln des kaputten PDFs:
pdf2ps findet eine File corruption und bricht mit einem gravierenden Konvertierungsfehler ab und gibt daher 1 zurück.

$\> pdf2ps kaputt.pdf 
 \*\*\*\* Warning: File has a corrupted %%EOF marker, or garbage after %%EOF.
 \*\*\*\* Warning: An error occurred while reading an XREF table.
 \*\*\*\* The file has been damaged. This may have been caused
 \*\*\*\* by a problem while converting or transfering the file.
 \*\*\*\* Ghostscript will attempt to recover the data.
Error: /typecheck in --run--
Operand stack:
 PageCount --nostringval-- --nostringval-- Count
Execution stack:
 %interp\_exit .runexec2 --nostringval-- --nostringval-- --nostringval--
 2 %stopped\_push --nostringval-- --nostringval-- --nostringval-- 
 false 1 %stopped\_push 1905 1 3 %oparray\_pop 1904 1 3 
 %oparray\_pop 1888 1 3 %oparray\_pop --nostringval-- 
 --nostringval-- --nostringval-- --nostringval-- --nostringval-- 
 --nostringval--
Dictionary stack:
 --dict:1150/1684(ro)(G)-- --dict:2/20(G)-- --dict:97/200(L)-- 
 --dict:97/200(L)-- --dict:107/127(ro)(G)-- --dict:275/300(ro)(G)-- 
 --dict:20/25(L)--
Current allocation mode is local
GPL Ghostscript 8.61: Unrecoverable error, exit code 1
$\> echo $?
1

Was man aber machen könnte ist, dass man zunächst die höchstwahrscheinlich schadhaften Dokumente mittels des Rückgabewerts identifiziert. In einem zweiten Schritt könnte man die verbleibenden Dokumente nochmal überprüfen und diesmal die Ausgabe von pdf2ps untersuchen und z.B. nach dem Text „The file has been damaged.“ suchen.

Allerdings denke ich dass dabei auch viele PDFs gefunden werden, die sich im Adobe Reader noch ohne optische Schäden darstellen lassen, die also nur fehlerhaft erstellt wurden.

Hallo deconstruct,
danke für die gründlichere Untersuchung und für die ergänzenden Hinweise.

Ich weiß nicht, wie stark und wie du das PDF beschädigt hast.

Nun, ich habe mit einem Hexeditor grössere Teile aus der Datei herausgeschnitten, wobei größere Teile so etwa 160 - 320 Byte bedeuten und einzelne Bytes per Zufall verändert.

Offenbar war der Schaden nicht so groß, dass Postscript den
Fehler nicht beheben oder ignorieren konnte und dennoch eine
Konvertierung durchführen konnte.

Das ist offenbar richtig, allerdings führte dieses „Beschädigen“ auch dazu, daß Teile vom Text fehlten und andere Formatierungen stimmten nicht mehr (z.B. fett war plötzlich normale Schrift). Ob man diese Dateien wegen des Rückgabewertes 0 dann als intakt definiert, obwohl sie irgendwie doch beschädigt sind, ist sicher Ansichtssache.

Solche Fehler haben oftmals viele PDFs, nicht aufgrund von
Beschädigung sondern wegen fehlerhafter Erstellung durch die
Software, mit der das PDF erzeugt wurde. Das ist daher
teilweise normal.

Es ist schon erstaunlich, daß z.B. in deinem Beispiel eine von Acrobat 6.0 erzeugte Datei Fehler aufweist. Ich meine, Adobe Acrobat ist ja nun keine Software, die seit gestern auf dem Markt ist und sich noch im Beta-Stadium befindet.

Naja, man sollte schon in erster Linie den Rückgabe-Wert
untersuchen. Wenn ein gravierender Fehler auftritt, und die
Konvertierung komplett scheitert, dann gibt pdf2ps einen Wert
ungleich 0 zurück. Dann ist die Datei mit großer
Wahrscheinlichkeit wirklich beschädigt.

Du hast Recht, aber wie gesagt, ab wann sieht man eine pdf-Datei als beschädigt an, erst wenn sie grob beschädigt ist (das %%EOF fehlt) oder schon, wenn z.B. Text fehlt? Aber wie Du sagst

In einem zweiten Schritt könnte
man die verbleibenden Dokumente nochmal überprüfen und diesmal
die Ausgabe von pdf2ps untersuchen und z.B. nach dem Text „The
file has been damaged.“ suchen.
Allerdings denke ich dass dabei auch viele PDFs gefunden
werden, die sich im Adobe Reader noch ohne optische Schäden
darstellen lassen, die also nur fehlerhaft erstellt wurden.

ist das leider nicht ganz so eindeutig.
Das ganze scheint sich also leider nicht ganz eindeutig lösen zu lassen.

Viele Grüße
Marvin

Danke euch beide
Moien

Das Skript hat zwar seine Zeit gebraucht aber die Resultate sehen bis jetzt richtig gut aus. Ich hab Stichproben gemacht und es sind owhl ein paar halbtote durch gegekommen. Aber die richtig grob beschädigten sind raus. Das hilft schonmal um einen Überblick zu bekommen.

Danke nochmal, die Idee mit den pdf-convertern hat mir ein paar Tage Arbeit erspart.

cu