【问题标题】:Two input file types at the same time in GNU parallel?GNU并行中同时有两种输入文件类型?
【发布时间】:2017-07-25 11:50:00
【问题描述】:

是否可以使用gnu parallel 的一个实例同时具有两种输入文件类型?

这个长命令:

find . -name \*.pdf | parallel -j 4 --progress --eta 'mkdir -p {.} && gs -dQUIET -dINTERPOLATE -dSAFER -dBATCH -dNOPAUSE -dPDFSETTINGS=/ebook -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'

一)

  • 为它读取的每个 pdf 创建一个文件夹(第一个输入文件类型)
  • 将带有Ghostscript 的pdf 转换为pgm 图像
  • 将它们移动到相应的文件夹中
  • 然后它将使用 tesseract 对每个 pgm(第二个输入文件类型)执行 OCR
  • 之后它将文本文件保存在各个文件夹中
  • 最后,删除所有 pgm 图像文件。

然而,上面的命令实际上是由两个命令结合&&组成的,把上面的例程分成两个独立的部分。结果是:

b)

  1. 首先将所有 pdf 文件转换为 pgm 图像文件(这会占用大量磁盘 空间!)
  2. 在它以 ocr 开头并随后清除 then 不需要的 pgm 图像文件。

这是不受欢迎的,因为它会在命令的第二部分执行之前耗尽我所有的磁盘空间!

可以将两个命令合并为一个,以便parallel 将完成前四个 pdf 的 a) 的整个过程(因为 parallel 同时执行 4 个作业 -j 4),之前转到接下来的四个 pdf 文件?

但是,parallel 似乎无法实现以下最小示例:

parallel -j 4 --progress --eta 'mkdir -p {.} && gs -sDEVICE=pgmraw -r300 -o {.}/{.}-%03d.pgm {}' && tesseract {} {.} -l deu_frak && rm {.}.pgm’ ::: *.pdf *.pgm

注意,最后两个输入文件扩展名::: *.pdf *.pgm

我该怎么做才能让parallel 遵循常规a)?

编辑:

这是我按照 Ole Tange 的建议尝试过的全部代码:

generate_pgm() {
  PDF="$1"
  find . -name \*.pdf | parallel 'mkdir -p {.} && gs -dQUIET -dINTERPOLATE -dSAFER -dBATCH -dNOPAUSE -dPDFSETTINGS=/ebook -dNumRenderingThreads=4 -sDEVICE=pgmraw -r300 -dTextAlphaBits=4 -sProcessColorModel=DeviceGray -sColorConversionStrategy=Gray -dOverrideICC -o {.}/{.}-%03d.pgm {}' ::: *.pdf
}
export -f generate_pgm
ocr() {
  PGM="$1"
  find . -name \*.pgm | parallel 'tesseract {} {.} -l deu_frak && rm {.}.pgm'
  rm "$PGM"
}
export -f ocr

time parallel -j 4 --progress --eta 'generate_pgm {}; parallel --argsep ,,, ocr ,,, pgm/*.pgm'  ::: *pdf

不幸的是,它没有成功,因为这个脚本基本上和我原来的脚本一样。它将创建所有 PDF 的文件夹并开始将所有 PDF 转换为 PGM,同时在第一个 PGM 图像上启动 OCR,而不是在开始接下来的四个之前对每四个 PDF 进行所有处理。

【问题讨论】:

    标签: pdf parallel-processing ocr tesseract


    【解决方案1】:

    我看到了 2 个解决方案:

    generate_pgm() {
      PDF="$1"
      # gs stuff
    }
    export -f generate_pgm
    ocr() {
      PGM="$1"
      # tesseract stuff
      rm "$PGM"
    }
    export -f ocr
    
    parallel 'generate_pgm {}; parallel --argsep ,,, ocr ,,, pgm/*.pgm'  ::: *pdf
    

    这将在转到下一个文件之前完全处理一个文件。

    但是,它最多可以运行 N^2 个进程(N=内核数)。为避免这种情况,请使用 --load:

    parallel 'generate_pgm {}; parallel --load 100% --argsep ,,, ocr ,,, pgm/*.pgm'  ::: *pdf
    

    这样,每个 CPU 核心应该只有一个活动进程。

    如果您希望它一次只转换一个 PDF:

    parallel -j1 'generate_pgm {}; parallel --argsep ,,, ocr ,,, pgm/*.pgm'  ::: *pdf
    

    另一种解决方案是使用dir处理器https://www.gnu.org/software/parallel/man.html#EXAMPLE:-GNU-Parallel-as-dir-processor

    nice parallel generate_pgm ::: *pdf &
    inotifywait -qmre MOVED_TO -e CLOSE_WRITE --format %w%f pgm_output_dir |   parallel ocr
    

    这样,pgm 生成将并行完成。这里的风险是,如果 pgm-generation 比 ocr 快得多,它仍然会填满你的磁盘。

    【讨论】:

    • 感谢 Ole Tange 的回复。我已经使用上述书面命令尝试了解决方案 1。但是,该脚本不会等待每个过程完成,而是简单地将 PDF 转换为 PGM。我忽略了什么吗?
    • 查看编辑以获取一次转换 1 个的解决方案。
    • 嗨 Ole Tange,不幸的是,脚本的编辑也不起作用。它不会超出将 PDF 转换为 PGM 的范围。没有完成 OCR。另外,它告诉我rm: pgm/*.pgm: No such file or directory
    • 也许解决方案在于如何让并行一次只找到4个PDF,比如for file in $(ls | grep -E "\.pdf$" | tail -4); do … ; done。但我不能把它放在一起。问题是编写一个循环,我们一次只显示 4 个并行的 PDF。
    猜你喜欢
    • 2021-04-29
    • 1970-01-01
    • 1970-01-01
    • 2023-01-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-10
    相关资源
    最近更新 更多