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 /?
- 例外
这是一个非常简单的 batch-file 解决方案,它假定:
_
后面的数字总是从 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"
这些是我在文件夹中的文件名
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 /?
- 例外
这是一个非常简单的 batch-file 解决方案,它假定:
_
后面的数字总是从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"