我正在尝试创建一个 for 循环,循环遍历目录中的 PNG 并使用 ImageMagick 将它们组合成对。
这是我所拥有的,但是++答不被 Windows CMD 接受:
for /f "delims=" %A in ('dir /b /od *.png') do magick "%A" "%(++A)" +append output-"%A".png
基本上,我想要发生的事情是这样的:
array = filenames;
for(f=0; array[f]; f++) // cycle through my files
magick array[f] array[++f]; // magick file1 file2... magick file3 file4...
如果能用一行完成则可以获得加分。
如果您能告诉我如何将 %A 转换为其迭代次数,则可获得额外加分。
例如,如果 %A 指向数组中的第三个文件名,我该如何让它输出“3”(如果计数从 0 开始,则输出“2”)。
免责声明:这些奖励积分都是理论上的,因为我是“新贡献者”,因此还不能投票。
答案1
它们没有。%A 只是一个只读字符串变量,仅在“for”迭代之间更新 - 您无法“增加”它。即使它是一个数组索引,Cmd 也没有预增量或任何其他内联表达式(字符串替换除外),甚至没有数组。
您可以使用“延迟扩展”来模拟数组,通过创建名为如下的变量%foo1%
:
@echo off
setlocal enabledelayedexpansion
set i=0
for /f "delims=" %%A in ('dir /b /od *.png') do (
set file!i!=%%A
set /a i=i+1
)
set /a n=%i%-2
for /l %%A in (0,2,%n%) do call :ugh %%A
goto :EOF
:ugh
:: A subroutine is needed to allow two levels of indirection, as otherwise
:: the %a% and %b% would be expanded when the 'for' line is *read* and not
:: during every iteration.
set /a a=%1
set /a b=%1+1
echo XXX: magick !file%a%! !file%b%! +append output-!file%b%!
goto :EOF
但是,更简单的方法是记住前一个文件而不是下一个文件:
@echo off
setlocal enabledelayedexpansion
set prev=
for /f "delims=" %%A in ('dir /b /od *.png') do (
if not "!prev!"=="" echo XXX: magick !prev! %%A +append output-%%A
if not "!prev!"=="" (set prev=) else (set prev=%%A)
)
但如果你想要单行命令,你应该使用 PowerShell:
$files = Get-ChildItem *.png | Sort-Object LastWriteTime
for ($i = 0; $i+1 -lt $files.Count; $i+=2) {
magick $files[$i] $files[$i+1] +append "output-$(files[$i])"
}
gci *.png | sort-object LastWriteTime | % {
if ($prev) { magick "$prev" "$_" +append "output-$_"; $prev = $null; }
else { $prev = $_ }
}
(这里gci
和是和的%
默认别名。)Get-ChildItem
ForEach-Item