ImageMagick - 合并具有部分文件名匹配的文件

ImageMagick - Merge files with partial filename matches

这些是我在文件夹中的文件名

1710190363_1.jpg
1710190363_2.jpg
1711140603_1.jpg
1711140603_2.jpg
1711140603_3.jpg
1711140603_4.jpg
1711140603_5.jpg

都是.jpg文件。文件名是动态的但唯一计数,前 10 位数字然后下划线后跟一位数字。

我正在尝试使用 imagemagick 将所有图像文件根据前十位数字转换为 pdf。我想要的输出如下

1710190363.pdf
1711140603.pdf

我手动得到这个 运行 -

convert 1710190363_1.JPG 1710190363_2.JPG 1710190363.pdf

但不知道如何运行循环

for %a in (*.jpg) do convert %a o_%a.pdf

谁能帮我写这个脚本。

使用bash

考虑:

for f in *_1.jpg; do convert "${f%_1.jpg}"*.jpg "${f%_1.jpg}.pdf"; done

或者,对于那些喜欢将命令分散在多行中的人:

for f in *_1.jpg
do
    convert "${f%_1.jpg}"*.jpg "${f%_1.jpg}.pdf"
done

以上假定jpeg文件名以.jpg结尾。如果您的 jpeg 文件名实际上以 .JPG 结尾,则使用:

for f in *_1.JPG; do convert "${f%_1.JPG}"*.JPG "${f%_1.JPG}.pdf"; done

例子

如果我们有一个包含这些文件的目录:

$ ls
1710190363_1.jpg  1710190363_2.jpg  1711140603_1.jpg  1711140603_2.jpg  1711140603_3.jpg  1711140603_4.jpg  1711140603_5.jpg

而我们的命令是:

for f in *_1.jpg; do convert "${f%_1.jpg}"*.jpg "${f%_1.jpg}.pdf"; done

我们的命令会导致 convert 执行两次,如下所示:

convert 1710190363_1.jpg 1710190363_2.jpg 1710190363.pdf
convert 1711140603_1.jpg 1711140603_2.jpg 1711140603_3.jpg 1711140603_4.jpg 1711140603_5.jpg 1711140603.pdf

工作原理

  • for f in *_1.jpg; do

    这将启动变量 f 的循环,其中 f 是目录中以 _1.jpg.

  • 结尾的每个文件的名称
  • convert "${f%_1.jpg}"*.jpg "${f%_1.jpg}.pdf"

    这对每组文件运行 convert

    ${f%_1.jpg} 是删除尾随 _1.jpg 的文件名。因此,glob "${f%_1.jpg}"*.jpg 扩展为具有相同起始前缀并以 .jpg 结尾的所有名称的列表。同样,"${f%_1.jpg}.pdf" 是输出文件的名称。

  • done

    这表示循环结束。

因此您希望按前 10 位数字对文件进行分组。第一个元素被下划线分割。

PowerShell

Get-ChildItem *.jpg | 
    Group-Object {$_.Name.Split('_')[0]} |
       ForEach-Object{
           &magick convert $($_.Group -join ' ') $_.Name+".pdf"
       }

批量解决方案

在此回复中我将给出一个纯批处理的解决方案。基于您想要根据名称中前 10 个相同数字转换文件的事实,我们可以提取所有文件名,仅获取前 10 个数字,然后将匹配的名称添加到一个字符串中。

这个过程有点复杂,但我在脚本中为每个过程放置了多个 Rem 语句(注释)来解释它在做什么。

ConvertFilesBasedOnFileMatched.bat:

@echo off
@setlocal EnableDelayedExpansion
set Count=1
set GetFName=1

Rem | Configuration
Set "MainDir=C:\New folder"
Set "Extension=.jpg"

Rem | Check If .XXX Files Exist
if not exist "!MainDir!\*!Extension!" (goto :EOF)

Rem | Grab All File Names
for %%A in ("!MainDir!\*!Extension!") do (

    Rem | Set as String, Grab First 10 Chars
    Set "CurrentName=%%~nA"
    Set "CurrentName=!CurrentName:~0,10!"

    Rem | Get First Name 
    If "!GetFName!"=="1" (

        Set "GetFName=2"

        Rem | Set as String, Grab First 10 Chars
        Set "FirstName=%%~nA"
        Set "FirstName=!FirstName:~0,10!"

    )

    Rem | Check For Differences
    If "!CurrentName!"=="!FirstName!" (

        set "CurrentList=!CurrentList! !CurrentName!_!Count!%%~xA"
        set /a "Count=!Count!+1"

    ) ELSE (

        Rem | Results Complete
        Convert !CurrentList:~1! !CurrentName!.pdf

        Rem | Reset For Future Loops
        set "Count=1"
        set "GetFName=1"
        set "CurrentList="

        Rem | Set Any Pending Data
        set "CurrentList=!CurrentList! !CurrentName!_!Count!%%~xA"
        set /a "Count=!Count!+1"

    )

)

Rem | Results Complete
Convert !CurrentList:~1! !CurrentName!.pdf

goto :EOF

此外,如果您需要为每张图片指定路径,请调整以下内容。

更改两个迭代:

set "CurrentList=!CurrentList! !CurrentName!_!Count!%%~xA" 

set "CurrentList=!CurrentList! !MainDir!\!CurrentName!_!Count!%%~xA"

有关命令的更多帮助,请在命令提示符中键入以下内容:

  • set /?
  • for /?
  • if /?
  • goto /?
  • 例外

这是一个非常简单的 解决方案,它假定:

  • _ 后面的数字总是从 1 开始计数;
  • 相同前缀文件的处理顺序无关紧要;

下面是要在批处理脚本中使用的代码:

for /F "delims=_" %%F in ('dir /B /A:-D "*_1.jpg"') do convert "%%F_*.jpg" "%%F.pdf"

这里是直接在命令提示符中使用的代码 (cmd):

for /F "delims=_" %F in ('dir /B /A:-D "*_1.jpg"') do @convert "%F_*.jpg" "%F.pdf"