Pdf 使用GNU parallel for OCR项目组合两个命令

Pdf 使用GNU parallel for OCR项目组合两个命令,pdf,parallel-processing,ocr,tesseract,pgm,Pdf,Parallel Processing,Ocr,Tesseract,Pgm,我想写一个脚本,它运行一个命令到OCRpdfs,在写入文本文件后删除生成的图像 我想要组合的两个命令如下 此命令用于创建文件夹,从每个PDF中提取pgm,并将其添加到每个文件夹中: time find . -name \*.pdf | parallel -j 4 --progress 'mkdir -p {.} && gs -dQUIET -dINTERPOLATE -dSAFER -dBATCH -dNOPAUSE -dPDFSETTINGS=/screen -dNumRend

我想写一个脚本,它运行一个命令到
OCR
pdfs,在写入文本文件后删除生成的图像

我想要组合的两个命令如下

此命令用于创建文件夹,从每个
PDF
中提取
pgm
,并将其添加到每个文件夹中:

time find . -name \*.pdf | parallel -j 4 --progress 'mkdir -p {.} && gs -dQUIET -dINTERPOLATE -dSAFER -dBATCH -dNOPAUSE -dPDFSETTINGS=/screen -dNumRenderingThreads=4 -sDEVICE=pgmraw -r300 -dTextAlphaBits=4 -sProcessColorModel=DeviceGray -sColorConversionStrategy=Gray -dOverrideICC -o {.}/{.}-%03d.pgm {}'
此命令执行OCR并删除生成的图像(
pgm
):

我想合并这两个命令,以便脚本在每次OCR后删除
pgm
图像。如果我运行上述命令,第一个命令将提取图像并占用我的磁盘空间,然后第二个命令将执行OCR,只有在这之后,作为最后一步删除图像

所以

  • 创建文件夹
  • 从PDF中提取PGM
  • 从PGM到txt的OCR
  • 删除刚刚使用过的PGM图像(丢失)
  • 基本上,我希望对每个
    PDF
    单独执行这4个步骤,而不是同时对所有
    PDF
    执行这4个步骤。我该怎么做

    编辑:

    我解决问题的第一次尝试是创建以下命令:

    time find . -name \*.pdf | parallel -j 4 -m --progress --eta 'mkdir -p {.} && gs -dQUIET -dINTERPOLATE -dSAFER -dBATCH -dNOPAUSE -dPDFSETTINGS=/screen -dNumRenderingThreads=4 -sDEVICE=pgmraw -r300 -dTextAlphaBits=4 -sProcessColorModel=DeviceGray -sColorConversionStrategy=Gray -dOverrideICC -o {.}/{.}-%03d.pgm {}' && time find . -name \*.pgm | parallel -j 4 --progress --eta 'tesseract {} {.} -l deu_frak && rm {.}.pgm'
    

    但是,tesseract找不到语言包。

    更新的答案

    我还没有测试过这个,请在你的一小部分文件的副本上运行它。如果您感到满意,可以在开始时使用
    DEBUG:
    关闭消息,它看起来不错:

    #!/bin/bash
    
    # Declare a function for "parallel" to call
    doit() {
        # Get name of PDF with and without extension
        withext="$1"
        noext="$2"
        echo "DEBUG: Processing $withext into $noext"
    
        # Make output directory
        mkdir -p "$noext"
    
        # Extract as PGM into subdirectory
        gs ... -o "$noext"/"${noext}-%03d.pgm $withext"
    
        # Go to target directory or die with error message
        cd "$noext" || { echo ERROR: Failed to cd to $noext ; exit 1; }
    
        # OCR and remove each PGM 
        n=0
        for f in *pgm; do
           echo "DEBUG: OCR $f into $n"
           tesseract "$f" "$n" -l deu_frak
           echo "DEBUG: Remove $f"
           rm "$f"
           ((n=n+1))
        done 
    }
    
    # Ensure the function is exported to subshells
    export -f doit
    
    find . -name \*.pdf -print0 | parallel -0 doit {} {.}
    
    您应该能够通过运行以下命令来测试
    doit()
    函数,而不必使用
    parallel

    doit someFile.pdf someFile
    
    原始答案

    如果您想对GNU Parallel中的每个参数做很多事情,最简单的方法是声明一个
    bash
    函数,然后调用它

    看起来是这样的:

    # Declare a function for "parallel" to call
    doit() {
        echo "$1" "$2"
        # mkdir something
        # extract PGM
        # do OCR
        # delete PGM
    }
    
    # Ensure the function is exported to subshells
    export -f doit
    
    find some files -print0 | parallel -0 doit {} {.}
    

    请引用$1和$2-否则您对-print0的使用不会产生真正的影响:
    echo“$1”“$2”
    。使用函数增加了额外的好处:在单个文件上进行测试非常容易。您好Mark Setchell,感谢您提出解决方案。看起来不错!不幸的是,我无法通过将我的命令复制粘贴到您的脚本中来实现它。请注意,我是这方面的初学者。请您用我的命令来创建一个可行的解决方案好吗?这太棒了!想象一下,您将“PDF”放在一个名为test的文件夹中。你将如何继续剧本?我已经在一个更完整的版本中做了我最好的尝试。。。请温柔小心地尝试:-)有更简单的方法吗?我的主要问题是,我无法将具有两个不同文件扩展名的输入文件通过管道并行传输到GNU,例如
    ls*pdf*pgm
    ,因为
    tesseract
    将停止并显示一条错误消息,即它无法打开
    pdfs
    。为什么我不能告诉并行查找命令中间的其他文件,就像我上面编辑的一个文件,我从<代码>查找开始。命名\*.pdf并更改为
    find-名称\*.pgm
    # Declare a function for "parallel" to call
    doit() {
        echo "$1" "$2"
        # mkdir something
        # extract PGM
        # do OCR
        # delete PGM
    }
    
    # Ensure the function is exported to subshells
    export -f doit
    
    find some files -print0 | parallel -0 doit {} {.}