【问题标题】:Combine two commands using GNU parallel for OCR project为 OCR 项目使用 GNU 并行组合两个命令
【发布时间】:2017-07-11 09:48:05
【问题描述】:

我想编写一个脚本,在文本文件写入后运行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):

time find . -name \*.pgm | parallel -j 4 --progress 'tesseract {} {.} -l deu_frak && rm {.}.pgm'

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

所以,

  1. 创建文件夹
  2. 从 PDF 中提取 PGM
  3. 从 PGM 到 txt 的 OCR
  4. 删除刚刚使用过的 PGM 图像(缺失)

基本上,我希望按此顺序对每个分隔的PDF 执行这 4 个步骤,而不是一次对所有PDF 执行。我该怎么做?

编辑:

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

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 找不到语言包。

【问题讨论】:

    标签: pdf parallel-processing ocr tesseract pgm


    【解决方案1】:

    更新答案

    我尚未对此进行测试,请在您的一小部分文件的副本上运行它。如果您觉得它看起来不错,您可以在开始时关闭带有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 {} {.}
    

    您应该能够在没有parallel 的情况下通过运行来测试doit() 函数:

    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,感谢您提出解决方案。这看起来不错的样子!不幸的是,我无法通过将我的命令复制“n”粘贴到您的脚本中来使其工作。请注意,我是此类事情的初学者。您能用我的命令创建一个可行的解决方案吗?这太棒了!想象一下,您将在名为 test 的文件夹中保存“PDF”。您将如何处理脚本?
    • 我已经为更完整的版本拍摄了最好的照片...请小心谨慎地尝试:-)
    • 有更简单的方法吗?我的主要问题是我无法将具有两个不同文件扩展名的输入文件通过管道传输到 GNU Parallel,例如 ls *pdf *pgm,因为 tesseract 将停止并显示无法打开 pdfs 的错误消息。为什么我不能告诉并行在命令中间查找其他文件,就像我上面编辑中的那个,我从 find . -name \*.pdf 开始并更改为 find . -name \*.pgm
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-20
    • 2017-01-14
    • 2017-09-09
    • 1970-01-01
    • 2018-07-07
    相关资源
    最近更新 更多