ImageMagick 将 tiffs 转换为带有顺序文件后缀的 pdf

ImageMagick convert tiffs to pdf with sequential file suffix

我有以下场景,我不是一个编码员(我也不了解 bash)。我什至没有一个基本的工作 bash 脚本可以分享,所以任何帮助将不胜感激。

我有一个文件共享,其中包含文档管理系统的 tiff(数千)。目标是将多个文件 tiff 转换并组合为单个文件 pdf(最好是 PDF/A 1a 格式)。

目录格式:

/Document Management Root     # This is root directory
 ./2009/                      # each subdirectory represents a year
 ./2010/
 ./2011/
 ....
 ./2016/
 ./2016/000009.001            
 ./2016/000010.001
              # files are stored flat - just thousands of files per year directory

文档管理系统存储带有序列号文件名和序列文件后缀的 tiff:

000009.001
000010.001
000011.002
000012.003
000013.001

文档的每一页都由后缀表示。当创建一个新的、不相关的文档时,后缀重新开始。在上面的示例中,000009.001 是单页 tiff。文件 000010.001000011.002000012.003 属于同一个文档(即页面都是相关的)。文件 000013.001 表示一个新文档。

我需要保留多页文档的第一个文件的文件名,以便文件名可以与文档管理系统数据库交叉引用以获取元数据。

我想出的伪代码是:

for each file in {tiff directory}
    while file extension is "001"
      convert file to pdf and place new pdf file in {pdf directory}
    else 
      convert multiple files to pdf and place new pd file in {pdf  directory}

但这似乎会产生转换所有 001 文件的副作用,而不管下一个文件是什么。

非常感谢任何帮助。

编辑 - 下面的两个答案都有效。第二个答案有效,但是我没有意识到我测试的数据集与上面的场景不同是我的错误。

因此,将以下脚本保存在您的登录 ($HOME) 目录中,作为 TIFF2PDF

#!/bin/bash
ls *[0-9] | awk -F'.' '
   /001$/ { if(NR>1)print cmd,outfile; outfile= ".pdf"; cmd="convert " [=10=];next}
          { cmd=cmd " " [=10=]}
   END    { print cmd,outfile}'

并通过进入终端和 运行ning:

使其可执行(只需要一次)
chmod +x TIFF2PDF    

然后将任何给定年份的一些文档复制到一个临时目录中进行尝试...然后转到该目录并 运行:

~/TIFF2PDF

示例输出

convert 000009.001 000009.pdf
convert 000010.001 000011.002 000012.003 000010.pdf
convert 000013.001 000013.pdf

如果看起来正确,您实际上可以像这样执行这些命令:

~/TIFF2PDF | bash

或者,如果您安装了 GNU Parallel,最好是:

~/TIFF2PDF | parallel

脚本说... "Generate a listing of all files whose names end in a digit and send that list to awk. In awk, use the dot as the separator between fields, so if the file is called 00011.0002, then [=24=] will be 00011.0002, </code> will be <code>00011 and </code> will be <code>0002. Now, if the filename ends in 0001, print the accumulated command and append the output filename. Then save the filename prefix with PDF extension as the output filename of the next PDF and start building up the next ImageMagick convert command. On subsequent lines (which don't end in 0001), add the filename to the list of filenames to include in the PDF. At the end, output any accumulated commands and append the output filename."


关于图像底部丑陋的黑色块,这是因为那里有一些微小的白色斑点,阻止 ImageMagick 删除黑色区域。我已经用红圈圈出来了:

如果您稍微模糊图片(以扩散斑点)然后获得 trim-box 的大小,您可以将其应用于原始的、未模糊的图像,如下所示:

trimbox=$(convert original.tif -blur x2 -bordercolor black -border 1 -fuzz 50% -format %@ info:)
convert original.tif -crop $trimbox result.tif

我建议您先复制所有图像,然后 运行 之后再进行 PDF 转换。由于您想要保存一个 TIFF 文件,但扩展名为 00010002,因此您需要将 ImageMagick 告知 trim 并强制将文件类型输出到 TIF:

original=XYZ.001
trimbox=$(convert $original -blur x2 -bordercolor black -border 1 -fuzz 50% -format %@ info:)
convert $original -crop $trimbox TIF:$original

作为@AlexP。提到,如果有大量文件,通配符可能会出现问题。在 OSX 上,ARG_MAX 非常高 (262144) 并且您的文件名大约为 10 个字符,因此如果一个目录中的文件超过 26,000 个左右,您可能会遇到问题。如果是这样,只需更改:

ls *[0-9] | awk ...

ls | grep "\d$" | awk ...

以下命令将转换整个 /Document Management Root 树(假设它是实际的绝对路径)正确处理所有子文件夹,即使名称包含空格字符,并正确跳过所有其他与 000000.000 命名不匹配的文件模式:

find '/Document Management Root' -type f -regextype sed -regex '.*/[0-9]\{6\}.001$' -exec bash -c 'p="{}"; d="${p:0: -10}"; n=${p: -10:6}; m=10#$n; c[1]="$d$n.001"; for i in {2..999}; do k=$((m+i-1)); l=$(printf "%s%06d.%03d" "$d" $k $i); [[ -f "$l" ]] || break; c[$i]="$l"; done; echo -n "convert"; printf " %q" "${c[@]}" "$d$n.pdf"; echo' \; | bash

干 运行 只需删除最后的 | bash

已更新以匹配 00000000.000 模式(为清楚起见拆分为多行):

find '/Document Management Root' -type f -regextype sed -regex '.*/[0-9]\{8\}.001$' -exec bash -c '
  pages[1]="{}"
  p1num="10#${pages[1]: -12:8}"
  for i in {2..999}; do
    nextpage=$(printf "%s%08d.%03d" "${pages[1]:0: -12}" $((p1num+i-1)) $i)
    [[ -f "$nextpage" ]] || break
    pages[i]="$nextpage"
  done
  echo -n "convert"
  printf " %q" "${pages[@]}" "${pages[1]:0: -3}pdf"
  echo
' \; | bash