Most convenient way to mass-process files in Windows is to use
FOR
loop.
Windows inherited batch scripting from MS-DOS, old operating system,
with all its inconsistencies and peculiar syntax. To use a
FOR
loop in Windows add below code to your
.BAT
file:
SETLOCAL EnableDelayedExpansion
FOR %%G IN (input\*.png) DO (
...do stuff
)
explanation
-
%G
is name of a variable that stores name of the file frominput
folder.*.png
that follows filters out everything but PNGs. -
SETLOCAL EnableDelayedExpansion
is required for Windows to properly expand values in the loop. If we do not declare this option,%%G
will be set to name of file that was found first. More on this peculiar mechanism can be found here: https://ss64.com/nt/delayedexpansion.html. A notable quote:
The SET command was first introduced with MS-DOS 2.0 in March 1983, at that time memory and CPU were very limited and the expansion of variables once per line was enough. Delayed Expansion was introduced some 16 years later in 1999 by which time millions of batch files had been written using the earlier syntax. Retaining immediate expansion as the default preserved backwards compatibility with existing batch file.
example
Script below adds black 4 pixel border to all PNG images from
input
directory. Results are saved to output
folder, changing file name from filename.png
to
filename-border.png
.
SETLOCAL EnableDelayedExpansion
FOR %%G IN (input\*.png) DO (
magick ^"%%G^" -bordercolor #000000 -border 4 ^"output\%%~nG-border.png^"
)
explanation
- things may go wrong if you don't proof your script against
whitespaces in the filenames. To prevent script go amiss, put quotes
around filenames. In batch scripting quotes need to be escaped.
Contrary to POSIX
\
in Windows you escape a character with a preceding^
. In other words^"%%G^"
puts quotes around filename stored in variable %G. -
%%~nG
is Windows idiom that expands to name of currently processed file.%%~xG
expands to file extension so we could write%%~nxG
if we wanted to preserve same filename and extension. But in our case, as we add-border
suffix, it made more sense to get just the filename. More on this variable expanding can be read here: http://www.embeddedframeworks.com/cmds/nt/syntax-args.html