PDF 파일 무결성 검증 / 확인


11

PDF 아카이브 (모든 디렉토리)에서 실행할 수있는 도구가 있습니까? 마지막으로 손상된 PDF를 나열 / 식별합니다.

컴퓨터 (Windows 시스템)에 수백 개의 PDF 파일 (문서 등)이 있으며 전자 메일을 통해 수십 개의 PDF를 받거나 보내야하는 경우가 많습니다. 지금 받거나 보내는 PDF가 손상된 것은 정상적인 일입니다. 소스 파일 (예 : Word 파일 또는 Tex 파일이 없거나 즉시 사용할 수없는 경우)로 인해 때때로 심각한 문제가 발생합니다.

이 수천 개의 PDF를 확인하는 것은 한정된 시간에 불가능하므로 한 번만 실행할 수있는 도구를 검색하여 모든 PDF (디렉토리 및 하위 디렉토리에있는)를 스캔 한 다음 마지막으로 다시 사용해야하는 파일 목록을 얻습니다. -창조하다. 지금까지는 그러한 도구가없는 것 같습니다.


2
리눅스라면 pdfinfo를 사용해보십시오. 살펴보기 : superuser.com/questions/580887/…
marcwho


답변:


6

PDFtk를 사용하면 PDF 파일이 유효한지 쉽게 확인할 수 있습니다. PDFtk 무료 GUI가 에서 사용할 수 있습니다 PDF 연구소 . 이 도구를 실행하면 파일 추가 버튼을 사용하여 여러 디렉토리에서 원하는만큼의 PDF를로드 할 수 있으며이 PDF 파일의 페이지에 매우 빠르게 액세스하기 시작합니다.

선택한 PDF 중 파일이 유효한 PDF가 아닌 경우이 유틸리티는 오류에 대한 메시지를 표시하고 선택 창에서 자동으로 제거합니다.

따라서이 절차를 PDFtk와 함께 사용하면 많은 시간을 절약 할 수 있습니다. 또한 멀티 코어 CPU가있는 경우이 유틸리티의 여러 인스턴스를 실행하고 각 인스턴스에 수백 개의 PDF를 넣을 수 있습니다.

지난 1 년 이후이 소프트웨어를 사용하고 있으며, 지금까지 가장 편리한 PDF 도구입니다.


2
또한, marcwho 언급 링크에서 사용할 수 (pdfinfo.exe), 당신이 할 수있는 도구를 사용하여 cdFolderContainingPDFs윈도우 쉘에서 다음 명령을 실행하고 로그 파일에 잘못된 PDF 파일을 표시합니다 : FORFILES /S /M *.pdf /C "cmd /c echo. & echo @path @fname & D:\XPDF_3.04\bin64\pdfinfo.exe @file" 1>text.txt 2>&1
Mubeen 샤 히드

4

xpdfbin-win package 및 cpdf.exe의 "pdfinfo.exe"를 사용하여 PDF 파일의 손상 여부를 확인했지만 필요하지 않은 바이너리는 포함하고 싶지 않았습니다.

최신 PDF 형식의 끝에 읽을 수있는 xml 데이터 카탈로그가 있다는 것을 읽었으므로 일반 창 NOTEPAD.exe로 PDF를 열고 읽을 수없는 데이터를지나 끝까지 스크롤하여 읽을 수있는 여러 키를 보았습니다. 하나의 키만 필요했지만 CreationDate와 ModDate를 모두 사용하기로했습니다.

다음 Powershell (PS) 스크립트는 현재 디렉토리의 모든 PDF 파일을 확인하고 각 파일의 상태를 텍스트 파일 (! RESULTS.log)로 출력합니다. 35,000 개의 PDF 파일에 대해이 작업을 실행하는 데 약 2 분이 걸렸습니다. PS를 처음 접하는 사람들을 위해 의견을 추가하려고했습니다. 이것이 누군가를 구하기를 바랍니다. 이 작업을 수행하는 더 좋은 방법이있을 수 있지만 이것은 내 목적을 위해 완벽하게 작동하며 오류를 자동으로 처리합니다. 처음에 다음을 정의해야 할 수도 있습니다. 화면에 오류가 표시되면 $ ErrorActionPreference = "SilentlyContinue"입니다.

다음을 텍스트 파일로 복사하고 적절하게 이름을 지정하거나 (예 : CheckPDF.ps1) PS를 열고 PDF 파일이 포함 된 디렉토리를 찾아 콘솔에 확인하여 붙여 넣으십시오.

#
# PowerShell v4.0
#
# Get all PDF files in current directory
#
$items = Get-ChildItem | Where-Object {$_.Extension -eq ".pdf"}

$logFile = "!RESULTS.log"
$badCounter = 0
$goodCounter = 0
$msg = "`n`nProcessing " + $items.count + " files... "
Write-Host -nonewline -foregroundcolor Yellow $msg
foreach ($item in $items)
{
    #
    # Suppress error messages
    #
    trap { Write-Output "Error trapped"; continue; }

    #
    # Read raw PDF data
    #
    $pdfText = Get-Content $item -raw

    #
    # Find string (near end of PDF file), if BAD file, ptr will be undefined or 0
    #
    $ptr1 = $pdfText.IndexOf("CreationDate")
    $ptr2 = $pdfText.IndexOf("ModDate")

    #
    # Grab raw dates from file - will ERR if ptr is 0
    #
    try { $cDate = $pdfText.SubString($ptr1, 37); $mDate = $pdfText.SubString($ptr2, 31); }

    #
    # Append filename and bad status to logfile and increment a counter
    # catch block is also where you would rename, move, or delete bad files.
    #
    catch { "*** $item is Broken ***" >> $logFile; $badCounter += 1; continue; }

    #
    # Append filename and good status to logfile
    #
    Write-Output "$item - OK" -EA "Stop" >> $logFile

    #
    # Increment a counter
    #
    $goodCounter += 1
}
#
# Calculate total
#
$totalCounter = $badCounter + $goodCounter

#
# Append 3 blank lines to end of logfile
#
1..3 | %{ Write-Output "" >> $logFile }

#
# Append statistics to end of logfile
#
Write-Output "Total: $totalCounter / BAD: $badCounter / GOOD: $goodCounter" >> $logFile
Write-Output "DONE!`n`n"

3

@ n0nuf의 발자취를 따라 pdfinfo를 사용하여 특정 폴더의 모든 PDF를 확인하고 cpdf를 통해 수정하려고 시도하는 배치 스크립트를 작성했습니다.

@ECHO OFF
FOR %%f in (*.PDF) DO (
    echo %%f
    pdfinfo "%%f" 2>&1 | findstr /I "error"  >nul 2>&1
    if not errorlevel 1 (
        echo "bad -> try to fix"
        @cpdf -i %%f -o %%f_.pdf 2>NUL
        mv %%f .\\bak\\%%f
    ) else (
       REM echo good        
    )
)
@ECHO ON

또는 bash 스크립트와 동일합니다.

for file in $(find . -iname "*.pdf")
do
    echo "$file"
    pdfinfo "$file" 2>&1 | grep -i 'error' &> /dev/null
    if [ $? == 0 ]; then
       echo "broken -> try to fix"
       cpdf -i "$file" -o "$file"_.pdf
    fi
done

깨진 PDF는 하위 폴더 \ bak으로 이동하고 다시 작성된 PDF는 접미사 _.pdf를 얻습니다 (완벽하지는 않지만 충분합니다). 참고 : 재 작성된 PDF에는 오류가 적으며 일반 PDF 뷰어에서 볼 수 있어야합니다. 그러나 이것이 모든 콘텐츠를 다시 얻는다는 의미는 아닙니다. 복구 할 수없는 콘텐츠는 빈 페이지로 이어집니다.

또한 @kraftydevil가 제안한 JHOVE (오픈 소스 파일 형식 식별, 유효성 검사 및 특성화 도구)를 사용하여 동일한 방법을 시도했습니다 .Linux의 명령 줄을 사용하여 PDF 파일이 손상 되었는지 확인 하고이 또한 유효한 접근 방법인지 확인할 수 있습니다. (먼저 성공하지 못했습니다. 그러나 JHOVE의 출력을 올바르게 처리하지 못했습니다.)

두 가지 접근 방식을 테스트하기 위해 텍스트 편집기를 사용하여 PDF에서 임의의 부분을 삭제하고 변경했습니다 (스트림이 제거되었으므로 PDF 뷰어에서 페이지가 렌더링되지 않고 PDF 태그가 변경되고 일부 비트가 이동했습니다). 결과는 다음 같습니다. pdfinfo와 JHOVE 모두 손상된 파일을 정확하게 발견 할 수 있습니다 (JHOVE는 경우에 따라 더 민감했습니다).

그리고 JHOVE에 해당하는 스크립트는 다음과 같습니다.

@ECHO OFF
FOR %%f in (*.PDF) DO (
    echo %%f
    "C:\Program Files (x86)\JHOVE\jhove.bat" -m pdf-hul %%f | findstr /C:"Well-Formed and valid" >nul 2>&1
    if not errorlevel 1 (
        echo good
    ) else (
        echo "bad -> try to fix"
        @cpdf -i %%f -o %%f_.pdf 2>NUL
        REM mv %%f .\\bak\\%%f
    )
)
@ECHO ON


@Scott 감사합니다. Windows 배치 FOR-loop는 훨씬 더 절약됩니다. bash 스크립트 구현을 샘플로 제공했습니다.
wp78de

리눅스도가는 길인 것 같습니다 : stackoverflow.com/a/9612232/8291949
wp78de
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.