如何获取没有匹配的.pdf文件的.jpg文件列表?

3
我将尝试将一个树结构中的一堆.jpg文件转换为.pdf,每个pdf有一页。我使用了Adobe Acrobat的批量(自定义操作)转换功能(顺便问一句,这是个好主意吗?一定有更好的方法吧!),但这是一个非常缓慢和痛苦的过程,在其中Acrobat在冻结前会表现出不稳定的行为,甚至拒绝一些文件。
因此,为了找到我需要创建的丢失的.pdf文件,我去了cygwin并尝试了一些如下命令:
$ find -name  *.jpg  -exec ls '{}/.jpg/pdf' \;

我希望这能将 {} 视为变量,用 .pdf 替换 .jpg,但替换并未发生。我该怎么做?
2个回答

5

请看下面:

find . -name '*.jpg' -exec \
    sh -c 'pdf="${1%.jpg}".pdf; test -f "$pdf" || echo missing: $pdf' -- {} \;

诀窍是将{}传递给子 Shell 作为命令行参数,这样您就可以在 shell 变量中使用模式替换,在本例中为 $1(第一个命令行参数)。
顺便说一句,"${1/.jpg/pdf}" 也可以工作,但 "${1%.jpg}".pdf 更准确。
该方法相对简单,但效率较低,因为它每个 JPG 文件都会启动一个新的 sh 进程。更高效但有点长的解决方案:
find . -name '*.jpg' -print0 | while read -d $'' f; do \
    pdf="${f%.jpg}".pdf; test -f "$pdf" || echo missing: $pdf; done

1
谢谢,这个完美地解决了问题。问题是:是否有一种方法可以在重复使用相同的子Shell的同时完成相同的操作,而不是为每个文件启动一个新进程? - Irina Rapoport
好问题,我添加了一个更高效的解决方案。 - janos
谢谢。$''是什么意思?同样,--又是什么意思? - Irina Rapoport
$'' 将输入分隔符设置为 NULL,这是因为我们使用了 -print0-- 是为了使其后的参数被设置为 $1 $2 ... 变量中的位置参数。 - janos

3

顺便问一下,这是个好主意吗?

不是的。PDF的 DCTDecode 滤波器需要JPG文件“原样”输入,这可能就是您想要的——将JPEG放入PDF容器中,而不进行任何重新压缩,并且没有您或任何软件触摸JPEG内容。因此,不仅Acrobat,而且例如在您的树上使用 ImageMagick 也不是一个好主意。我想不到现成的工具来将JPEG包装成PDF,但可以通过小程序帮助。

use strict;
use warnings;
use File::Find;
use PDF::Reuse;
use Image::Info qw(image_info dim);

find(sub {
    return unless /\.jpg$/i;
    my ($w, $h) = dim(image_info($_));
    prFile($_.'.pdf');
    prMbox(0, 0, $w, $h);
    prAdd("q $w 0 0 $h 0 0 cm /".prJpeg($_, $w, $h)." Do Q\n");
    prEnd()
}, $ARGV[0]);

它应该非常快,期望树根作为参数,并且只是像我说的那样:将你的JPG格式转换为PDF格式。

p.s. 至少需要一些检查--检查 $w 和 $h 是否定义?PDF::Reuse 允许记录日志,可能会有帮助。

p.p.s. 注意,此模块假定 RGB 格式,但如果您的 JPG 格式可以是灰度或 CMYK 格式--在 image_info 哈希中检查并对 PDF::Reuse 源代码进行小修改。它还假定 72 dpi -- 否则,也请检查 image_info 哈希中的分辨率并调整上面的 prMbox 和 prAdd 调用的参数。

另一个更新:

以上代码是 Perl 代码。在 Windows 上,您可以安装 ActiveState 的版本(然后使用其 PPM 实用程序添加模块),或者 Strawberry Perl(并使用 cpan 客户端安装模块)。File::Find 是核心模块。PDF::Reuse 和 Image::Info 需要手动安装。

安装好这些,然后将以上源代码保存为例如 jpegs_2_pdfs.pl,将几个RGB jpeg 示例放入某个文件夹中(树状结构内部或仅是简单列表--现在不重要),然后从命令提示符中运行:

perl jpegs_2_pdfs.pl path_to_my_folder

它应该为每个JPG文件创建PDF。这只是为了让你尝试一下。如果你觉得你需要所有这些,而且你愿意并且可以花时间和精力,并且它是值得的——那么我将详细说明“如果文件不是RGB”和“分辨率不是72 dpi时该怎么做”——虽然我不会为你写出一个准备好的解决方案,你需要自己编码 :-)
请注意,尽管我说“避免重新压缩”,但即使你保留像素尺寸并使用JPEG重新压缩,也会有质量损失。
convert file.jpg -compress JPEG file.pdf

绝对可以忽略不计。 Convert 是ImageMagick的工具,如果您不懂编程(只需为您的树创建一个批处理文件),这可能是您的选择。

同时,请注意,当您说“jpg混合彩色/灰度/黑白”时,这是不可能的,因为您不能将二值图像保存为jpeg格式。


这是什么,@VadimR,Javascript?Adobe插件?我该如何运行它?它假定72 dpi在哪里?我的jpg都是混合分辨率和混合颜色/灰度/黑白的,我多年来一直用不同的扫描仪扫描我的文件,不知道扫描仪是否会执行CMYK或其他操作。现在我正在将它们转换为PDF以进行OCR,所以你是对的,我确实不想失去质量。但我需要更多信息! - Irina Rapoport
谢谢您的更新。我已在Adobe论坛中发布了我的问题(有没有一种无损导入到PDF、OCR然后“优化”并在一个动作中保存的方式?),如果他们无法回答我的问题,我将使用ImageMagick的Convert。我从未学过Perl...我知道Ruby的基础知识,应该学习JavaScript,但今天我不会学习Perl...我正在尝试在今天完成这个任务。通过“混合图像”的意思是指一堆不同分辨率和压缩的黑白、灰度和彩色图像都排列在一棵树上。我也不知道它们是RGB还是CMYK。 - Irina Rapoport
@user2712050,感谢您接受了这个答案,但我认为对于原始主要问题的直接回答是Janos的。我回答了“副问题”,只是因为我也觉得它很有趣 :-) - user2846289
你可能是对的,我改了。你的回答对我来说非常重要,但我确实表明它是一个附带问题。 - Irina Rapoport

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接