#!/usr/bin/env bash # ocr-scan.sh — recursively OCR un-OCR'd PDFs # Deps: ocrmypdf, poppler-utils (pdftotext), tesseract-ocr # Optional: python3-langdetect (for -a auto-detect) set -euo pipefail LANG_CODE="eng" AUTO_DETECT=false MIN_CHARS=50 # chars per page threshold — below = needs OCR DIR="." usage() { cat </dev/null | head -c 500) if [[ -z "$sample" ]]; then echo "eng"; return fi python3 - </dev/null || echo "eng" from langdetect import detect try: print("$(echo "$sample" | tr -d "'" | head -c 300)") except: print("eng") EOF # simpler: call python directly python3 -c " from langdetect import detect import sys try: lang = detect('''$sample''') print(lang) except: print('eng') " 2>/dev/null || echo "eng" } needs_ocr() { local pdf="$1" local pages pages=$(pdfinfo "$pdf" 2>/dev/null | awk '/^Pages:/{print $2}') [[ -z "$pages" || "$pages" -eq 0 ]] && pages=1 local chars chars=$(pdftotext "$pdf" - 2>/dev/null | wc -c) local threshold=$(( pages * MIN_CHARS )) [[ "$chars" -lt "$threshold" ]] } find "$DIR" -type f -iname "*.pdf" ! -iname "*_OCR.pdf" | while read -r pdf; do out="${pdf%.pdf}_OCR.pdf" if [[ -f "$out" ]]; then echo "[SKIP] Already has OCR copy: $out" continue fi if ! needs_ocr "$pdf"; then echo "[SKIP] Already has text: $pdf" continue fi lang="$LANG_CODE" if $AUTO_DETECT; then detected=$(detect_lang "$pdf") lang=$(map_lang "$detected") echo "[DETECT] $pdf → $detected → $lang" fi echo "[OCR] $pdf (lang: $lang) → $out" ocrmypdf \ --language "$lang" \ --output-type pdfa \ --skip-text \ --rotate-pages \ --deskew \ "$pdf" "$out" \ && echo "[DONE] $out" \ || echo "[FAIL] $pdf" done